Genuinely остановить элемент от привязки - развязать элемент - AngularJS

Я пытаюсь выяснить, как я могу остановить элемент DOM от привязки данных из области действия в angular.

Я знаю, что вы могли бы сделать это с помощью инструкций if и всех, но существует ли подлинный и постоянный способ остановить привязку элемента в angular, но сохранить добавленный контент?

Так сказать, у меня это

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

И я меняю модель так, чтобы div менялся.

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

Затем я нажимаю кнопку, которая отвязывает ее, поэтому, если я изменю модель на 'Welcome Universe', я не буду <div> быть таким же, как раньше. Это

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

Я знаю, что есть много других способов сделать это, но я не знаю никакого способа действительно отпереть элемент, не клонируя его и заменяя старый, перебирающий атрибуты и текст .ect.

Демо-версия: http://jsfiddle.net/a9tZY/

Таким образом, делая это, это не должно влиять на модель или другие элементы, которые привязаны к этой модели.

Короче говоря, Tell angular, чтобы оставить элемент навсегда.

Ответ 1

UPDATE

Способ сделать это - создать новую область для элемента с такой директивой.

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, элемент будет unbind-ed

REF-1: Добавьте атрибут unbind true к элементу, чтобы директива узнала, какой элемент вы отключаете.

REF-2: Широковещать событие unbind по всем областям, чтобы директива знала, что вы хотите развязать элемент. Убедитесь, что вы сначала добавили атрибут. --- В зависимости от вашего макета приложения вам может потребоваться использовать $rootScope.$broadcast

REF-3: когда передается событие unbind

REF-4. Если элемент, связанный с директивой, имеет истинный атрибут unbind

REF-5. Затем уничтожьте область действия, заданную директивой. Мы должны использовать setTimeout, потому что я думаю, что angular пытается что-то сделать после события $on, и мы получаем ошибку, поэтому использование setTimeout предотвратит эту ошибку. Хотя он срабатывает мгновенно.

Это работает с несколькими элементами, вот хорошая демонстрация.

Демо: http://jsfiddle.net/wzAXu/2/

Ответ 2

Мне это показалось любопытным, поэтому я немного пошутил. Сначала я попробовал метод "unbind()", предложенный в другом ответе, но который работал только с удалением обработчиков событий из этого элемента, когда то, что вы на самом деле пытаетесь сделать, это удалить область angular из этого элемента. Для выполнения этой функции может быть какая-то скрытая функция angular, но это тоже очень хорошо:

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

Это сохраняет модель (и обновляет все, что еще привязано к ней), но удаляет привязку с элемента. Кроме того, в вашем примере выше нет привязки для удаления, потому что вы не привязываетесь ни к какому элементу, просто отображаете выражение модели inline. Мой пример показывает это в действии: http://jsfiddle.net/3jQMx/1/

Ответ 3

Вы можете вызвать метод unbind, который перестает прослушивать элемент, в котором присутствует атрибут ng-model. Смотрите скрипту: http://jsfiddle.net/jexgF/

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

unbind удаляет все прослушиватели событий, поэтому всякий раз, когда происходят какие-либо изменения, он не прослушивает их и, следовательно, не проходит цикл angular. Я также предположил, что вы не используете jQuery, но если это так, вы можете использовать лучший селектор, чем document.getElementById