替换的替代方法:对于angularJS指令为true
所以替换:在不久的将来会从AngularJS中删除true.我理解为什么,但我认为没有它可以很好地支持在AngularJS中开发的某些场景.
我想创建一个如下所示的按钮组件: <button ng-click="doSomething()" important-model="outerCtrl.theModel"> important text </button> 这是从一个属性启动的,例如,像这样: <div my-button-component> </div> 现在使用替换我得到我想要的,但由于它被弃用我想避免使用它,所以我想也许我可以这样做: <button my-button-component ng-click="doSomething()" important-model="outerCtrl.theModel"> </button> 让指令在里面插入’重要文本’. 这个解决方案很奇怪,因为虽然ng-click可以访问指令范围并且可以按预期工作(就像它在指令模板中一样),但是我的组件是一个按钮,可以点击的事实,以及应该定义的任何其他内容在我的组件内部,而不是在我选择使用它的模板中. 另一个选择就是为所有这些提供一个div包装器,由于前端约束,这是不可接受的. 最后一个选择是接受我无法使用指令控制根元素的类型或属性,并以程序方式应用单击侦听器和任何其他行为(例如ng-class).这对我来说似乎不是一个好的解决方案,尽管它可能是目前为止最好的解决方案. 这不是我第一次感觉到你对指令的根元素有多少控制权有问题,我是否认为这是错误的? 解决方法
首先,我不认为替换:在不久的将来会被删除.它已被弃用,但在任何有角度的1.X版本中摆脱它将是一个突破性的变化,所以我认为你好,直到Angular 2.0发布. Angular 2.0将会破坏更多,所以我不会过分担心如何使现有的应用程序无需替换:true. 2.0可能具有某种等效功能,但将现有应用程序迁移到2.0可能不是您想要做的事情.
但是,假设地回答你的问题: replace:true做两件事: 1)它用指令模板替换DOM中的元素. 2)它将DOM中元素的属性与指令模板合并. (2)实际上是该特征的非平凡部分,围绕它的边缘情况是Angular团队想要摆脱它的原因. 例如,如果您的元素是: <div some-directive ng-click="doSomething()"><div> 而someDirective有一个模板: <div ng-click="doSomethingInDirective()"></div> 更换节点后哪个优先?替换的逻辑:true目前做出这些决定并为您提供一切. 如果由于某种原因,替换:true从1.X中删除(它不会),你做什么? 答案是你将不得不手动执行替换:true现在做,哪个(简化)是: 1)获取原始元素的属性 2)将原始元素的属性与指令模板合并,跟踪作为指令的属性和非指令的属性,并跟踪每个指令的声明位置(在原始元素或模板中). 3)通过编译合并属性指令和指令模板指令来编译指令模板. 4)将作为原始元素一部分的合并属性指令链接到$parent范围,将所有其他指令链接到指令范围.将指令链接到指令范围 4a)必要时执行转换(transclude:true,模板包括ng-transclude) 5)用完全链接的指令模板替换原始元素. 以下是Github的相关代码: if (directive.replace) { replaceDirective = directive; if (jqLiteIsTextNode(directiveValue)) { $template = []; } else { $template = removeComments(wrapTemplate(directive.templateNamespace,trim(directiveValue))); } compileNode = $template[0]; if ($template.length != 1 || compileNode.nodeType !== NODE_TYPE_ELEMENT) { throw $compileMinErr('tplrt',"Template for directive '{0}' must have exactly one root element. {1}",directiveName,''); } replaceWith(jqCollection,$compileNode,compileNode); var newTemplateAttrs = {$attr: {}}; // combine directives from the original node and from the template: // - take the array of directives for this element // - split it into two parts,those that already applied (processed) and those that weren't (unprocessed) // - collect directives from the template and sort them by priority // - combine directives as: processed + template + unprocessed var templateDirectives = collectDirectives(compileNode,[],newTemplateAttrs); var unprocessedDirectives = directives.splice(i + 1,directives.length - (i + 1)); if (newIsolateScopeDirective) { markDirectivesAsIsolate(templateDirectives); } directives = directives.concat(templateDirectives).concat(unprocessedDirectives); mergeTemplateAttributes(templateAttrs,newTemplateAttrs); 我不会很快出去写你自己的版本.任何需要替换的代码:true也需要Angular 1.X,因此它将受支持.当您准备使用Angular 2.0编写新应用程序时,将会有另一种(希望更好)的方法来执行此操作. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |