Angular scope.watch 在指令中不起作用
Posted
技术标签:
【中文标题】Angular scope.watch 在指令中不起作用【英文标题】:Angular scope.watch not working in directive 【发布时间】:2016-09-14 13:39:25 【问题描述】:我有一个观察列表的角度指令,然后在编辑列表时创建自定义选择。我有这个在一个页面上工作,但它拒绝在另一个页面上工作。我不知道为什么 - 但是当列表发生变化时,手表似乎没有捕捉到。
我在这里重现了错误 - 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】:我找到了答案。原来以下行不起作用
scope.$watch(scope.sourceList, (newVal) =>
改成下面这个问题就解决了
scope.$watch('sourceList', (newVal) =>
【讨论】:
以上是关于Angular scope.watch 在指令中不起作用的主要内容,如果未能解决你的问题,请参考以下文章
Angular - 带有 controllerAs、bindToController 和 $scope.$watch 的指令
Angular $scope.$watch 用于仅从表单更改的变量(ng-model 指令)
AngularJS:$scope.$watch 没有更新从自定义指令上的 $resource 获取的值