Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

angular ng-show / ng-hide not working correctly with ng-bind-html

I want to set ng-show or ng-hide for my elements in html string and pass it to view with ng-bind-html but ng-show / ng-hide not working and my element always visible.

This is my controller code:

  $scope.my = {
    messageTrue: true,
    messageFalse: false
  };

  $scope.HtmlContent = "<div ng-show='{{my.messageFalse}}'>This is incorrect (ng-show & my.messageFalse={{my.messageFalse}})</div> ";
  $scope.trustedHtml = $interpolate($scope.HtmlContent)($scope);

And this is my view code:

<div ng-show="my.messageTrue">This is correct (ng-show & my.messageTrue={{my.messageTrue}})</div>
<div ng-hide="my.messageFalse">This is correct (ng-hide & my.messageFalse={{my.messageFalse}})</div>
<div ng-bind-html="trustedHtml"></div>

This is a Plnkr for my question. (Thanks for Xaero)

Sorry for my bad English. Thanks

like image 557
b24 Avatar asked Jan 08 '23 22:01

b24


2 Answers

This is because the html you are injecting has not yet been compiled and linked by angular, so it is just being displayed "as is". It's being treated the same way your markup would be treated if you didn't include angular.js at all.

The solution is to create a directive that works similar to ng-bind-html, but that also includes a step for compiling and linking the html fragment.

This link is an example of such a directive.

Here is the code:

angular.module('ngHtmlCompile', []).
    directive('ngHtmlCompile', function($compile) {
    return {
        restrict: 'A',
        link: function(scope, element, attrs) {
            scope.$watch(attrs.ngHtmlCompile, function(newValue, oldValue) {
                element.html(newValue);
                $compile(element.contents())(scope);
            });
        }
    }
});

and the usage.

<div ng-html-compile="trustedHtml"></div> 

And here is the working Plunk

like image 190
Joe Enzminger Avatar answered Jan 20 '23 09:01

Joe Enzminger


Have you injected $interpolate in the controller, and also added ngSanitize in the module?

Here's a working plnkr: http://plnkr.co/edit/qTsUzi04tCNdK5BAZvDa?p=preview

// controller.js
var app = angular.module('app');

app.controller('indexController', indexController);

function indexController($scope, $interpolate) {
  $scope.my = {
    messageTrue: true,
    messageFalse: false
  };

  $scope.HtmlContent = "<div ng-show='{{my.messageTrue}}'>{{my.messageTrue}}</div> ";
  $scope.trustedHtml = $interpolate($scope.HtmlContent)($scope);
}

// app.js
angular.module('app', ['ngSanitize']);

// index.html
<!DOCTYPE html>
<html>
<head></head>

<body ng-app="app" ng-controller="indexController">
<div ng-show="my.messageTrue">{{my.messageTrue}}</div>
<div ng-show="my.messageFalse">{{1 + 1}}</div>

<div ng-bind-html="trustedHtml"></div>

<script data-require="angular.js@*" data-semver="1.4.0-beta.4" src="https://code.angularjs.org/1.4.0-beta.4/angular.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.9/angular-sanitize.js"></script>
<script src="app.js"></script>
<script src="controller.js"></script>
</body>
</html>

and this link on using ng-bind-html: How to output html through AngularJS template?

like image 34
Xaero Avatar answered Jan 20 '23 10:01

Xaero