不确定度指令,传入参量类别,然后该指令列出该类别下的所有不确定度。
新增页面用到了三个该指令,只有最后一个成功,前两个都没有数据。
探究源码
以下是指令源码:
'use strict'; /** * @ngdoc directive * @name webappApp.directive:yunzhiAccuracyUncertainty * @description * # yunzhiAccuracyUncertainty * 不确定度指令 * zhangxishuo */ angular.module('webappApp') .directive('yunzhiAccuracyUncertainty', function($filter) { return { templateUrl: 'views/directive/yunzhiAccuracyUncertainty.html', restrict: 'E', scope: { parameterCategory: '=', // 参量类别 ngModel: '=' // 不确定度 }, link: function postLink(scope, element, attrs) { var self = this; // 初始化 self.init = function() { // 初始化不确定度空列表 scope.accuracyList = []; // 监听参量类别 scope.$watch('parameterCategory', self.watchParameterCategory); // 监听不确定度 scope.$watch('ngModel', self.watchNgModel); }; // 监听参量类别 self.watchParameterCategory = function(newValue) { if (newValue && newValue.id) { // 设置不确定度列表 scope.accuracyList = newValue.accuracyUncertaintyList; // 过滤数据 self.filter(); } }; // 监听不确定度 self.watchNgModel = function(newValue) { if (newValue && newValue.id) { // 设置默认选中 scope.selected = newValue; } }; // 过滤数据 self.filter = function() { angular.forEach(scope.accuracyList, function(accuracy) { // 过滤不确定度 accuracy._value = $filter('yunzhiAccuracyWithUnit')(accuracy); }); }; // 更新模型 self.updateModel = function(selected) { // 更新数据 scope.ngModel = selected; }; // 传给视图 scope.updateModel = self.updateModel; self.init(); } }; });
尝试
尝试打印了一下scope.accuracyList,果然有问题。
前两个都是空,最后一个数组有值。
想不明白,这里明明监听参量类别,并将scope的accuracyList设置了值啊?为什么没有呢?
scope
尝试打印一下scope。
去关注scope的$id就行了。
依次打印的是:
504 508 // 第一个指令 506 508 // 第二个指令 508 508 // 第三个指令
前两个指令执行时赋值的是一个scope,而过滤的又是另一个scope,所以过滤不出数据,最后一个是同一scope,所以正常输出。
原因
官方文档
HTML Compiler允许开发者教会浏览器一些新的语法,AngularJS称这个为指令。
Compiler是一个遍历DOM去搜寻属性的AngularJS服务,编译分为以下两个阶段。
Compile:遍历DOM并收集所有的指令,返回结果是一个linking函数。
Link:使用scope整合指令并产生动态视图,任何scope模型上的改变都会反映到视图上,任何视图上的用户交互也会反映到scope模型上。
指令如何编译
AngularJS操作DOM节点而不是字符串,这很重要。但通常,你不需要关注这个,因为当页面加载时,浏览器会自动把HTML转换为DOM。
指令编译有以下三阶段:
$compile遍历DOM并匹配指令,如果compiler发现有匹配指令的元素,就会将该指令添加到指令列表中。一个元素可能匹配多个指令。
一旦所有匹配DOM元素的指令都被确定,然后compiler会根据优先级对指令进行排序。每一个指令的compile函数都会被执行,每一个compile函数都有操作DOM的机会。compile会返回link函数,这些函数被组合成一个“组合的”link函数,它能调用每个指令返回的link函数。
$compile会调用上一步中的“组合的”link函数来链接scope和模板。
下面是官方的示意代码: