手机版

解决AngularJS多指令范围问题

时间:2021-08-29 来源:互联网 编辑:宝哥软件园 浏览:

问题描述

不确定性指令,传入参数类别,然后该指令列出该类别下的所有不确定性。

新页面使用了三条指令,只有最后一条成功,前两条没有数据。

探索源代码

以下是指令源代码:

使用“严格”;/* * * @ ng doc指令* @ name webapp app . directive : yunjiacuruyunna certificate * @ description * # yunjiacuruyunna certificate *测不准指令* Zhang xishuo */angular . module(' webapp ')。指令(' yunzhiAccuracyUncertainty ',函数($ filter){ return { templateurl : ' views/指令/yuzhiaccuracyunambition . html ',restrict: 'E ',Scope : {参数类别:'=',//参数类别ngModel: '=' //不确定性},link :函数post link (scope,element,attrs){ var self=this;//初始化self.init=function() {//初始化不确定范围的空列表。accurate list=[];//监控参数类别范围。$ watch('参数类别',self。watch parameter category);//监控不确定性范围。$ watch ('ng model ',self。watching model);};//监控参数类别自身。watch parameter category=function(新值){if(新值new value . id){//设置不确定性列表范围。精确列表=新值。准确性不确定性列表;//筛选数据self . filter();} };//监控不确定性自我。watchnmodel=function(new value){ if(new value new value . id){//set scope . selected=new value默认情况下;} };//自过滤数据。filter=function () {angular。foreach(范围。准确度列表,函数(准确度){//滤波器不确定度准确度。_ value=$ filter(' yunjiiaccurayywithounit ')(精度);});};//更新模型自身。updatemodel=函数(选定){//更新数据范围. ngModel=选定;};//传递给view scope . update model=self . update model;self . init();} };});尝试

我试着打印范围。精确列表,但是有一个问题。

前两个是空的,最后一个数组有一个值。

我不明白。我在这里清楚地监控参数类别,并设置范围的精确列表的值。为什么不呢?

范围

尝试打印范围。

只需注意scope的$id。

依次打印的有:

504508 //第一条指令506508 //第二条指令508508 //第三条指令的前两条指令被分配了一个作用域,而另一条作用域被过滤,所以数据无法被过滤,最后一条是同一个作用域,所以正常输出。

理由

正式文件

HTML编译器- AngularJS

HTML Compiler允许开发人员教浏览器一些新的语法,AngularJS称之为指令。

编译器是一个AngularJS服务,它遍历DOM来搜索属性。编译分为以下两个阶段。

编译:遍历DOM,收集所有指令,返回结果是一个链接函数。链接:使用范围集成指令并生成动态视图。范围模型的任何变化都将反映在视图上,视图上的任何用户交互也将反映在范围模型上。如何编译指令

重要的是,AngularJS在DOM节点上而不是字符串上运行。但通常情况下,你并不需要注意这一点,因为当页面加载后,浏览器会自动将HTML转换为DOM。

指令编译有三个阶段:

$compile遍历DOM并匹配指令。如果编译器找到与该指令匹配的元素,它会将该指令添加到指令列表中。一个元素可以匹配多个指令。一旦确定了所有与DOM元素匹配的指令,编译器将根据优先级对指令进行排序。每个指令的编译函数都会被执行,每个编译函数都有机会操作DOM。Compile返回link函数,它被组合成一个“组合”的link函数,可以调用每个指令返回的link函数。$compile将调用上一步中的“组合”链接函数来链接范围和模板。以下是官方示意图代码:

//HTML字符串var HTML=' div ng-bind=' exp '/div ';//将HTML字符串转换为DOM模板vartemplate=angular . element(HTML);//编译DOM模板并返回链接函数var linkFn=$compile(模板);//用scope var元素=linkFn(作用域)链接编译后的模板;//添加到DOM parent.appendChild(元素);分析

编译时只执行一次,只要页面中有一条指令,指令的link方法就执行一次。

因此,AngularJS用$compile编译了我的指令,然后看到在我的页面中使用了三个指令,它们都是独立的作用域,所以创建了三个作用域。

然后用这三个作用域调用link函数。

如前所述,AngularJS将链接函数组合成一个“组合”链接函数,所以我们可以猜测组合函数中链接函数的数量与指令的数量是一致的,所以一个链接函数被调用三次,链接函数只有一个实例!

LinkFn(作用域)作为link函数的输入参数传入作用域。

上面的事件监控没问题,把传入的作用域绑定到视图,然后添加到DOM,然后就和这个链接函数没有关系了。

但是这个过滤器不起作用。

第一个作用域调用,过滤函数是过滤第一个作用域的精度列表,第二个作用域调用,过滤函数是过滤第二个作用域的精度列表。

因此,在第三次执行时,第三个作用域覆盖前两个作用域,链接函数中的filter函数成为过滤最后一个作用域的accuracyList。

!-不确定性-ui-select ng-model=' selected '主题=' bootstrap ' ng-change=' updatemodel(selected)Ui-select-match占位符='请选择' { $ select . selected . _ value } }/Ui-select-match Ui-select-choices repeat='准确性列表中的准确性' div ng-bind-html='准确性。_value '/div/ui-select-choices/ui-select,所以这里的下拉框显示的是不确定性过滤后的_ value的值,这里的空字符串不明显,所以加test测试一下

因此,绑定到此视图的范围是正确的,但是数据是在时间侦听后过滤的。因为过滤的数据不是当前范围的数据,所以准确性。_value没有值,未定义,因此显示一个空字符串。

解决办法

理解了原理之后,就很容易解决问题了,只需要把过滤器从作用域中分离出来,这样就不受每次执行不同作用域的影响了。

摘要

很多书本上没有的东西,需要我们自己去发现,去分析,去解决。

以前遇到指令编译问题时,打开从别人博客里学来的手工编译方法。

angular.module('webappApp ')。指令(' reCompile ',函数($ COMPILE){ return { restrict : ' A ',link: function postLink(作用域,元素,Attr){//侦听ngbindhtmttrs。$ observe ('ngBindHtml ',function(){//如果元素使用ngBindHtml指令if (attrs.ngBindHtml) {//重新编译$ compile(元素[0])。儿童)(范围);} });} };});我记得以前的要求是数据被过滤器过滤,并返回一段HTML代码。虽然可以使用ng-bind-html将这段代码添加到DOM中,但是这段代码中有一个说明。因为这个指令不在开头,所以不会编译这个指令。

因此,有必要编写一个重新编译的指令,并手动编译动态创建的指令。

我记得当时我并没有完全理解这段代码。现在,在学习了编译指令之后,我看了前面的代码。原来一切都是那么简单。

以上就是本文的全部内容。希望对大家的学习有帮助,支持我们。

版权声明:解决AngularJS多指令范围问题是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。