Nested Directive Not Updating View(DOM) Element in AngularJs

453 Views Asked by At

I've made a nested directive, and tried to call it from a html view,but not updating the view element in html.

I can get the updated value from the calling controller but can't see the updated effect in view level.

Here is the Js

    // Code goes here
"use strict";
var myApp=angular.module("myApp",[]);

myApp.directive("selectDirective", [function () {
    return {
        restrict: "E",
        template: '<select class="form-control input-sm dropdown" data-ng-model="model.args.selectedItem" data-ng-options="item[model.args.displayField] for item in model.args.source" data-ng-change="model.itemChange(model.args.selectedItem)"><option value="">Select Any Item</option></select>',
        scope: {
        },
        bindToController: { args: "=" },
        link: function (scope, element, attrs) {
            var self = scope.model || {};
            var initializeControl = function () {
                if (self.args == undefined) {
                    self.args = {};
                }
                if (self.args.method == undefined) {
                    self.args.method = {};
                }
                if (self.args.isDisabled == undefined) {
                    self.args.isDisabled = false;
                }
                if (self.args.displayField == undefined) {
                    self.args.displayField = '';
                    //alert('Display Field is blank for dropdown control.')
                }
                if (self.args.valueField == undefined) {
                    self.args.valueField = '';
                    //alert('Value Field is blank for dropdown control.')
                }
                if (self.args.source == undefined) {
                    self.args.source = {};
                }
                if (self.args.hide == undefined) {
                    self.args.hide = false;
                }
            }
            var assignMethod = function () {
                self.args.method =
                    {
                        setEnable: function (args) {
                            self.args.isDisabled = !args;
                        },
                        setVisible: function (args) {
                            self.args.hide = !args;
                        },
                        getText: function () {
                            return self.args.selectedText;
                        },
                        getValue: function () {
                            return self.args.selectedValue;
                        },
                        setItem: function (item) {
                            if (item != undefined) {
                                var index = self.args.source.indexOf(item);
                                self.args.selectedText = item[self.args.displayField];
                                self.args.selectedValue = item[self.args.valueField];
                                self.args.selectedItem = item;
                                self.args.selectedIndex = index;
                            }

                        }
                    }
            }
            self.itemChange = function (item) {

                if (item != undefined) {
                    var index = self.args.source.indexOf(item);
                    self.args.selectedText = item[self.args.displayField];
                    self.args.selectedValue = item[self.args.valueField];
                    self.args.selectedItem = item;
                    self.args.selectedIndex = index;
                }
            }

            initializeControl();
            assignMethod();

        },
        controller: function () { },
        controllerAs: 'model'
    }
}]);
myApp.directive("stateDirective", [function () {
    return {
        restrict: "E",
        template: '<select-directive args="model.args"></select-directive>',
        scope: {},
        bindToController: { args: "=" },
        link: function (scope, element, attrs) {
            var self = scope.model || {};

            var initializeControl = function () {
                if (self.args == undefined) {
                    self.args = {};
                }
                var sourceList = [{ id: 1, name: "AA", value: "AA" },
                              { id: 2, name: "AB", value: "AB" },
                              { id: 3, name: "ABD", value: "ABD" },
                              { id: 4, name: "ABE", value: "ABE" },
                              { id: 5, name: "ACT", value: "ACT" },
                              { id: 6, name: "AE", value: "AE" }];
                self.args.source = sourceList;
                self.args.displayField = 'name';
                self.args.valueField = 'value';
            }();

        },
        controller: function () {

        },
        controllerAs: 'model'
    }
}]);
myApp.controller("homeController", ['$interval', function ($interval) {
    var self = this;

    var initializeControl = function () {

        self.state1 = {};
        self.state2 = {};

        self.ClickMe = function () {
            debugger;
            aler(1);
            self.state2.method.setItem(self.state1.selectedItem);
        }

        self.ClickMe2 = function () {
            debugger;
             aler(1);
            var x1 = self.state1;
            var x2 = self.state2;
        }



    };
    $interval(function () {
    }, 500);

    initializeControl();
}]);

Here is the Html:

     <div class="cold-md-12" ng-controller="homeController as model">
    <h1>Home Page</h1>
    <state-directive args="model.state1"></state-directive>
    <br />
    <input type="button" value="ClickMe" data-ng-click="model.ClickMe()" />
    <state-directive args="model.state2"></state-directive><br />
    <input type="button" value="Submit" data-ng-click="model.ClickMe2()" />
</div>

Fiddle Here.

N.B: i tried using $watch and $timeout in directive and controller also but didn't work.

2

There are 2 best solutions below

0
On BEST ANSWER

Just added track by in ng-option.

I just change the data-ng-options value from

item[model.args.displayField] for item in model.args.source

to

item[model.args.displayField] for item in model.args.source track by item[model.args.valueField] 

and it's working perfectly.

1
On

In the event that scope.model is not initialized, you're assigning {} to self in your linking function. But then you never actually place it on the controller. If scope.model exists, you're fine, because you're then binding everything to the controller, which is bound to scope, but if it's not stuff goes wrong. Which I'm guessing is what's happening.

Although, if I may be so bold, I'd say that naming your controller model is very misleading. Because in the development world models and controllers are two very different things.

Cheers, Aaron