简体   繁体   中英

AngularJS ng-show does not work with new DOM elements

I have some div s with ng-show directives which work fine when the page loads.

Now, under some conditions, new DOM elements (again div s) would appear on my page. They already have the ng-show directive in them but for some reason these expressions are not being evaluated. Is there any way to 'force' AngularJS to reeval all ng-show expressions?

Not a JS developer, managed to do a little demo: https://jsfiddle.net/xasjeqe5/1/

Edit: link to demo was wrong. Also here is the code:

HTML:

<div ng-controller="MyCtrl">
    <div ng-show="good(1)">TEST1</div>
    <div ng-show="good(2)">TEST1</div>

    <input type="button" ng-click="add()" value="add"/>
</div>

JavaScript:

var myApp = angular.module('myApp',[]);

function MyCtrl($scope) {

$scope.good = function(i) {
    return i>5;
};

$scope.add = function() {
    var newDiv = document.createElement("div");
    var newContent = document.createTextNode("I am invisible!");
    var att = document.createAttribute("ng-show");
    att.value = "good(4)";
    newDiv.setAttributeNode(att);
    newDiv.appendChild(newContent);
    document.body.appendChild(newDiv); 
};
}

Edit2: to avoid some of the confusion.

I am not really trying just to integrate AngularJS to be able to add new elements. The reason for my question and the demo is that I have some server-side rendering involved which returns prepared HTML data. This HTML data has to be "inserted" into the existing page (that is why all the manipulation is happening). The prepared HTML data on the other hand is a mixture of plain HTML and AngularJS directives.

You are creating and attaching DOM nodes manually, outside of the Angular world. Angular does not know anything about them, so they will not behave as you are expecting.

Rather than thinking in terms of DOM elements, Angular encourages you to think in terms of binding against a data model. Then Angular can handle most of the DOM manipulation for you.

Here is an example that shows adding elements to the screen and optionally hiding them with ng-show . Notice that we are not creating DOM elements explicitly - instead we are adding items to an array and changing their properties. Then, in our view we bind to this array using a repeater, allowing Angular to create the new <div> elements for us. Each item also has one raw HTML property that we bind against using ng-bind-html . We need to pass this through the $sce service to tell Angular to trust our HTML string. This turns off Angular's built in XSS protection that would otherwise kick in and cause an error.

Fiddle: https://jsfiddle.net/z4odkfne/1/

Controller

var myApp = angular.module('myApp',[]);

function MyCtrl($scope, $sce) {

    $scope.items = [];

    $scope.add = function() {
        $scope.items.push({
            name: "New item", 
            show: true,
            html: $sce.trustAsHtml('<span style="color:red">some html</span>')
        })
    };

    $scope.hide = function(item) {
        item.show = false;
    }
}

View

<div ng-controller="MyCtrl">
    <div ng-repeat="item in items"
         ng-show="item.show">
        {{item.name}} {{$index}}
        <span ng-bind-html="item.html"></span>
        <input type="button" ng-click="hide(item)" value="Hide me" />
    </div>

    <input type="button" ng-click="add()" value="add"/>
</div>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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