【问题标题】:Genuinely stop a element from binding - unbind an element - AngularJS真正阻止元素绑定 - 取消绑定元素 - AngularJS
【发布时间】:2013-08-16 21:41:05
【问题描述】:

我正在尝试找出如何阻止 DOM 元素从角度范围内绑定数据。

我知道您可以使用 if 语句和所有语句来做到这一点,但是是否有一种真正永久的方法来停止以角度绑定元素但保留添加的内容?

所以说我有这个

<div ng-bind=​"content" class=​"ng-binding">​Welcome​</div>​

我改变了模型,让 div 变成了这个。

<div ng-bind=​"content" class=​"ng-binding">​Welcome​ World</div>​

然后我点击解除绑定的按钮,所以如果我将模型更改为'Welcome Universe',我不想&lt;div&gt; 和以前一样。这个

<div ng-bind=​"content" class=​"ng-binding">​Welcome​ World</div>​

我知道还有很多其他方法可以做到这一点,但我不知道有什么方法可以真正解除绑定元素,而不是克隆它并替换循环遍历属性和文本的旧元素..ect

演示:http://jsfiddle.net/a9tZY/

因此,这样做不会影响模型或绑定到该模型的其他元素。

长话短说,告诉 Angular 永远不要管这个元素。

【问题讨论】:

  • 这个的用例是什么?
  • 我实际上在使用ng-style,我不想停止绑定某些元素,而是继续绑定其他元素,我使用了一个简单的文本示例,这样更容易理解,但总体结果将停止绑定到该元素的任何内容。
  • 这篇文章可能有用:stackoverflow.com/questions/13651578/…
  • 这很有趣,因为在包含所有观察者的范围内有一个 $$watchers 对象,您可以通过这种方式解除绑定,但我无法找到一种方法来识别观察者是哪个,@Sharondio 感谢您的链接,同样的问题,但不是我要找的。​​span>
  • 我真的希望这是可能的

标签: javascript angularjs angularjs-scope


【解决方案1】:

更新

这样做的方法是使用这样的指令在元素上创建一个新范围。

yourModule.directive('unbindable', function(){
    return { scope: true };
});

然后像这样将它应用到你的元素上

<div unbindable id="yourId"></div>

然后解除绑定此元素与您执行此操作的任何更新。

angular.element( document.getElementById('yourId') ).scope().$destroy();

完成,这是一个演示。

演示:http://jsfiddle.net/KQD6H/

因此,这会在元素上创建一个新范围,并且仅在所有范围都从其父范围继承所有数据时才有效。所以作用域与父作用域基本相同,但允许你在不影响父作用域的情况下销毁作用域。因为这个元素被赋予了它自己的作用域,所以当你销毁它时,它不会像所有其他元素一样恢复父作用域,如果这有意义的话 0.o

此行以下的所有内容都是我的原始答案,我会留在这里以防有人喜欢这种方式


我已经通过unbindable 指令真正实现了这一点。 当您在元素上设置了unbinable 指令后,解除绑定元素所需的一切就是这个。

yourElement.attr('unbind', 'true'); // Ref 1
$scope.$broadcast('unbind'); // Ref 2

这是指令。

app.directive('unbindable', function(){
    return {
        scope: true, // This is what lets us do the magic.
        controller: function( $scope, $element){ 
            $scope.$on('unbind', function(){ // Ref 3
                if($element.attr('unbind') === 'true'){ // Ref 4
                    window.setTimeout(function(){ $scope.$destroy() }, 0);//Ref 5
                }
            });
        }
    }
});

然后你像这样设置你的元素。

<h1 unbindable></h1>

因此,每当您将unbind="true" 属性添加到h1 并广播unbind 时,该元素将被解除绑定

REF-1:将 unbind true 属性添加到元素,以便指令知道您要取消绑定的元素。

REF-2: 在范围内广播 unbind 事件,以便指令知道您要取消绑定元素 - 确保首先添加属性。 --- 根据您的应用布局,您可能需要使用$rootScope.$broadcast

REF-3:解绑事件广播时

REF-4:如果与指令关联的元素具有真正的 unbind 属性

REF-5:然后销毁指令生成的作用域。我们必须使用setTimeout,因为我认为角度尝试在$on 事件之后做某事并且我们得到一个错误,所以使用setTimeout 将防止该错误。虽然它会立即触发。

这适用于多个元素,这是一个不错的演示。

演示:http://jsfiddle.net/wzAXu/2/

【讨论】:

  • 这很甜蜜。
  • 所以你需要指令来创建元素范围?
  • 这很奇怪,因为元素原型包含 .scope()。你会认为元素范围是存在的,而指令只是抓住了它。但也许它需要指令来公开它。
  • @Sharondio 我想你会发现使用指令 scope: true,它为元素创建了一个新的范围,但是范围仍然从父范围继承,所以新范围仍然继承父范围数据,但是当您删除范围时,您正在删除新范围,因此该元素不再属于任何范围,如果这有意义的话?
  • 当心,这在生产中是行不通的。当您禁用调试信息 ($compileProvider.debugInfoEnabled(true)) 时,.scope().isolateScope() 将不起作用。
【解决方案2】:

这个让我很好奇,所以我做了一些探索。起初,我尝试了另一个答案中建议的“unbind()”方法,但这仅适用于从元素中删除事件处理程序时,您实际上想要做的是从元素中删除角度范围。 Angular 中可能有一些更简洁的隐藏函数可以做到这一点,但这也很好用:

angular.element(document.getElementById('txtElem')).scope().$destroy();

这会保留模型(并更新仍然绑定到它的任何其他内容),但会从元素中删除绑定。此外,在上面的示例中,没有要删除的绑定,因为您没有绑定到任何元素,只是内联显示模型表达式。我的示例显示了这一点:http://jsfiddle.net/3jQMx/1/

【讨论】:

  • 我知道这绝对是要走的路,但它消除了对所有人的约束。 jsfiddle.net/3jQMx/2
  • 现在我真的很好奇。必须有一种简单的方法来做到这一点。是时候深入研究角源了……
【解决方案3】:

您可以调用 unbind 方法停止监听存在 ng-model 属性的元素。见小提琴:http://jsfiddle.net/jexgF/

angular.element(document.getElementById('txtElem')).unbind()

unbind 删除所有事件侦听器,因此无论何时进行任何更改,它都不会侦听这些事件,因此不会通过角度循环。我还假设您没有使用 jQuery,但如果您使用了,您可以使用比 document.getElementById 更好的选择器

【讨论】:

  • 我不想删除这个元素Stop me when your done: 而不是模型上的绑定
  • 不知道为什么它被否决了,我确实试图解决这个问题,从接受的答案来看,看起来有点帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-19
  • 2018-01-21
  • 1970-01-01
  • 2013-12-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多