Angular scope.watch不在指令中工作

时间:2016-05-18 07:48:38

标签: angularjs typescript angular-material

我有一个观察列表的角度指令,然后在编辑列表时创建自定义选择。我在一个页面上工作,但它拒绝在另一个页面上工作。我不知道为什么 - 但是当列表发生变化时,手表似乎没有捕获。

我在这里重现了错误 - http://codepen.io/jagdipa/pen/Ramjez - 有人可以帮忙吗?!

angular.module('MyApp',['ngMaterial', 'ngMessages', 'material.svgAssetsCache'])
.controller('AppCtrl', function($scope) {
  $scope.clearValue = function() {
    $scope.myModel = undefined;
  };
  $scope.save = function() {
    alert('Form was valid!');
  };

  var Titles =[{"Title":"Mr"},{"Title":"Master"},{"Title":"Miss"},{"Title":"Mrs"}];
  $scope.titles = Titles;

});





module MyApp.Directives {

    interface TcSelectListScope extends ng.IScope {
        sourceList: any[];
        sourceListKey: string;
        sourceListValue: string;
    }

    export class TcSelectListController {
        static $inject = [];

        constructor() {
        }

    }

    export class TcSelectList {
        public restrict = "A";
        public require = ["ngModel", "^form", '^^mdInputContainer', "select"];
        public controller = TcSelectListController;
        public controllerAs = 'selectController';
        public scope = {
            sourceList: "="
        }

        constructor(private $compile: ng.ICompileService) {
        }

        public compile(tElement, tAttributes) {
            var $compile = this.$compile;
            var _cacheService = this.cacheService;

            return function postLink(scope, element, attrs, controller) {
                var ngModelCtrl = controller[0];
                var mdInputContainerCtrl = controller[2];
                var selectCtrl = controller[3];
                console.log(selectCtrl);



              /*if (scope.sourceList == undefined)
                {
                  scope.sourceList = [];
                }*/
                scope.$watch(scope.sourceList, scope.onModelChanged, true);
                //scope.$watchCollection(scope.sourceList, scope.onModelChanged);

                scope.onModelChanged = () => {
                    console.log('tc select list directive 2');
                    console.log(scope.sourceList);

                    if (attrs.sourceListKey == undefined) {
                        throw ("The source-list-key needs to be defined for tc-select-list");
                    }
                    if (attrs.sourceListValue == undefined) {
                        throw ("The source-list-value needs to be defined for tc-select-list");
                    }

                    var html = undefined;
                        html = buildSelect();

                    html = markSelected(html);
                    element.append(html);

                }



                element.on("click", function () {
                    mdInputContainerCtrl.setHasValue(true);
                });

                element.bind("blur", function () {
                    if (ngModelCtrl.$viewValue == undefined) {
                        mdInputContainerCtrl.setHasValue(false);
                    }
                });

                element.bind("change", function () {
                    mdInputContainerCtrl.setHasValue(true);
                });

                function buildSelect() {
                    var html = ``;

                    angular.forEach(scope.sourceList, (val, index) => {
                        var itemKey = scope.sourceList[index][attrs.sourceListKey];
                        var itemValue = scope.sourceList[index][attrs.sourceListValue];
                        var selected = ``;

                        html += `<option label="` + itemValue +
                            `" value="` + itemKey +
                            `" ` + selected +
                            ` >` + itemValue + ` < /option>`;
                    });

                    return html;
                }

                function markSelected(html) {
                    if (ngModelCtrl.$modelValue != undefined && ngModelCtrl.$modelValue != null) {
                        html = html.replace(`value="` + ngModelCtrl.$modelValue + `"`,
                            `value="` + ngModelCtrl.$modelValue + `" selected`)
                    }
                    return html
                }
            }
        }

        static factory() { 
            var directive = ($compile, cacheService) => new TcSelectList($compile, cacheService);
            directive.$inject = ["$compile"];
            return directive;
        }
    }

    angular.module("MyApp").directive("tcSelectList", TcSelectList.factory());
}


<div ng-controller="AppCtrl" layout="column" layout-align="center center" style="min-height: 300px;" ng-cloak="" class="selectdemoValidations" ng-app="MyApp">
  <form name="myForm">


    <p>Note that invalid styling only applies if invalid and dirty</p>
    <md-input-container class="md-block">
      <label>Favorite Number</label>
      <md-select name="myModel" ng-model="myModel" required="">
        <md-option value="1">One 1</md-option>
        <md-option value="2">Two</md-option>
      </md-select>
      <div class="errors" ng-messages="myForm.myModel.$error" ng-if="myForm.$dirty">
        <div ng-message="required">Required</div>
      </div>
    </md-input-container>
    <div layout="row">
      <md-button ng-click="clearValue()" ng-disabled="!myModel" style="margin-right: 20px;">Clear</md-button>
      <md-button ng-click="save()" ng-disabled="myForm.$invalid" class="md-primary" layout="" layout-align="center end">Save</md-button>
    </div>



    <md-input-container class="no-errors">
      <label>{{translations["Title"]}}</label>
      <div class="tc-select">
        <select name="title"
                tc-select-list
                ng-model="myModel.Title"
                source-list="titles"
                source-list-key="Title"
                source-list-value="Title"></select>
      </div>
    </md-input-container>
    <br/>
    {{titles}}
    <br/>       
    Title = {{myModel.Title}}
  </forms>




</div>

1 个答案:

答案 0 :(得分:0)

我找到了答案。原来以下一行无效

scope.$watch(scope.sourceList, (newVal) => {

将其更改为以下内容将问题排除

scope.$watch('sourceList', (newVal) => {