htmlangularjsangular-directiveisolate-scope

Nested Directive Not Updating View(DOM) Element in AngularJs


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.


Solution

  • 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.