简体   繁体   English

真正阻止元素绑定 - 取消绑定元素 - AngularJS

[英]Genuinely stop a element from binding - unbind an element - AngularJS

I'm trying to find out how I can stop a DOM element from binding data from the scope in angular. 我试图找出如何阻止DOM元素绑定角度范围内的数据。

I know that you could do this with if statements and all, but is there a genuine & permanent way to stop binding a element in angular but keep the content that was added? 我知道你可以用if语句和所有语句来做这个,但是有没有一种真正的永久方法来阻止角度元素绑定但保留添加的内容?

So say i have this 所以说我有这个

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

And i change the model so that the div changes to this. 我改变模型,以便div改变为这个。

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

Then I click the button that will unbind it, so if I change the model to 'Welcome Universe' , I wan't the <div> to be the same as before. 然后我点击将取消绑定它的按钮,所以如果我将模型更改为'Welcome Universe' ,我不希望<div>与之前相同。 This 这个

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

I know there are many other ways to do this, but i don't know any way to genuinely unbind the element, without cloning it and replacing the old one looping through the attributes and text..ect 我知道还有很多其他的方法可以做到这一点,但我不知道如何真正解开元素,没有克隆它并用属性和文本替换旧的循环。

Demo thing: http://jsfiddle.net/a9tZY/ 演示用品: http//jsfiddle.net/a9tZY/

So, by doing this, it shouldn't affect the model or other elements that are binding to that model. 因此,通过这样做,它不应该影响模型或绑定到该模型的其他元素。

Long story short, Tell Angular to leave the element alone forever. 长话短说,Tell Angular永远留下元素。

UPDATE UPDATE

The way to do this is to create a new scope on the element with a directive like so. 执行此操作的方法是使用类似指令在元素上创建新范围。

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

And apply it to your element like so 并将其应用于您的元素

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

Then to unbind this element from any updates you do this. 然后从您执行此操作的任何更新中取消绑定此元素。

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

Done, here's a demo. 完成,这是一个演示。

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

So this creates a new scope on the element and only works because all scopes inherit all data from their parent scopes. 因此,这会在元素上创建一个新范围,并且只能工作,因为所有范围都从其父范围继承所有数据。 so the scope is basically the same as the parent scope, but allows you to destroy the scope without affecting the parent scope. 因此范围与父范围基本相同,但允许您在不影响父范围的情况下销毁范围。 Because this element was given it's own scope, when you destroy it it doesn't get the parent scope back like all of the other elements, if that makes sense 0.o 因为这个元素被赋予它自己的范围,所以当你破坏它时,它不会像所有其他元素一样返回父范围,如果这有意义的话。

Everything below this line was my original answer,I'll leave it here incase someone prefers this way 这一行以下的所有内容都是我原来的答案,我会留在这里,因为有人喜欢这种方式


I have managed to achieve this genuinely with a unbindable directive. 我已经设法通过一个unbindable指令真正实现了这一unbindable When you have the unbinable directive set up on the element all that is required to unbind the element is this. 当您在元素上设置了unbinable指令时,取消绑定元素所需的全部内容就是这个。

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

Here is the directive. 这是指令。

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
                }
            });
        }
    }
});

and you set your element up like this. 并且你将元素设置为这样。

<h1 unbindable></h1>

So whenever you add the unbind="true" attribute to the h1 and broadcast unbind the element will be unbind-ed 因此,无论何时将unbind="true"属性添加到h1并广播unbind该元素都将被解除绑定

REF-1: Add the unbind true attribute to the element so that the directive knows what element you are unbinding. REF-1:将unbind true属性添加到元素中,以便指令知道要解除绑定的元素。

REF-2: Broadcast the unbind event across the scopes so that the directive knows that you want to unbind a element - Make sure you add the attribute first. REF-2:在范围内广播解除绑定事件,以便指令知道您要取消绑定元素 - 确保首先添加属性。 --- Depending on your app layout, you might need to use $rootScope.$broadcast ---根据您的应用布局,您可能需要使用$rootScope.$broadcast

REF-3 : When the unbind event is broadcasted REF-3 :广播unbind事件时

REF-4 : If the element associated with the directive has a true unbind attribute REF-4 :如果与指令关联的元素具有真正的unbind属性

REF-5 : Then destroy the scope made by the directive. REF-5 :然后销毁指令所作的范围。 We have to use setTimeout because I think angular tries to do something after the $on event and we get a error, so using setTimeout will prevent that error. 我们必须使用setTimeout因为我认为angular尝试在$on事件之后执行某些操作并且我们收到错误,因此使用setTimeout将防止该错误。 Although it fires instantly. 虽然它瞬间发射。

This works on multiple elements, here is a nice demo. 这适用于多个元素,这是一个很好的演示。

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

This one got me curious, so I did some poking around. 这个让我好奇,所以我做了一些探讨。 At first I tried the "unbind()" method suggested in the other answer, but that only worked with removing event handlers from the element when what you're actually trying to do is remove the angular scope from the element. 起初我尝试了另一个答案中建议的“unbind()”方法,但这只适用于从元素中删除事件处理程序,而实际上你要做的就是从元素中删除角度范围。 There may be some neater hidden function in Angular to do this, but this works just fine too: 在Angular中可能有一些更好的隐藏功能来执行此操作,但这也可以正常工作:

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

This retains the model (and updates anything else still bound to it), but removes the binding from the element. 这将保留模型(并更新仍绑定到它的任何其他内容),但会从元素中删除绑定。 Also, in your example above, there is no binding to remove because you aren't binding to any element, just displaying the model expression inline. 此外,在上面的示例中,没有要删除的绑定,因为您没有绑定到任何元素,只是显示内联的模型表达式。 My example shows this in action: http://jsfiddle.net/3jQMx/1/ 我的例子显示了这个: http//jsfiddle.net/3jQMx/1/

You can call the unbind method that stops listening to the element where the ng-model attribute is present. 您可以调用unbind方法来停止侦听存在ng-model属性的元素。 See fiddle: http://jsfiddle.net/jexgF/ 请参阅小提琴: http//jsfiddle.net/jexgF/

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

unbind removes all event listeners, so whenever any changes are made, it wont listen for those and hence not go through the angular loop. unbind删除所有事件监听器,因此无论何时进行任何更改,它都不会监听它们,因此不会通过角度循环。 I have also assumed that you are not using jQuery, but if you are, you can use a better selector than document.getElementById 我还假设您没有使用jQuery,但如果您使用jQuery,则可以使用比document.getElementById更好的选择器

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM