angularjsangularjs-filterwatchangularjs-ng-modelng-bind-html

Watch ng-model in ng-bind-html using AngularJs


Here is my Markup

<div ng-app="myApp" ng-controller="myCtrl">
    <input type="text" ng-model="name">
    <p ng-bind-html="myText|unsafe"></p>
</div>

I am using this code

var app = angular.module("myApp", ['ngSanitize']);
app.controller("myCtrl", function($scope) {
    $scope.myText = "My name is: <h1>{{name}}</h1>";
    $scope.name="Habib";
});
app.filter('unsafe', function ($sce) {
    return function(val) {
        return $sce.trustAsHtml(val);
    };
});

Output:

My name is: {{}}

Desired Output:

My name is: Habib

I want it should also reflect value from textbox.


Solution

  • EDIT

    The reason you are having issues with getting $scope.name bound is because ng-bind-html does not bind that html to the current scope. You can use a directive to fix this. Here is an answer that fixes your issue.

    Here is a plunker that adds the directive and shows the behavior you are looking for.

    Here is the directive that was added that fixes your issue:

    app.directive('compileTemplate', function($compile, $parse){
       return {
           link: function(scope, element, attr){
               var parsed = $parse(attr.ngBindHtml);
               function getStringValue() {
                    return (parsed(scope) || '').toString();
               }
    
                // Recompile if the template changes
                scope.$watch(getStringValue, function() {
                    // The -9999 makes it skip directives
                    // so that we do not recompile ourselves
                    $compile(element, null, -9999)(scope);  
                });
            }
        }
    });
    

    You need to declare $scope.name="Habib" before the myText scope variable.

    var app = angular.module("myApp", ['ngSanitize']);
    app.controller("myCtrl", function($scope) {
        $scope.name="Habib";
        $scope.myText = "My name is: <h1>{{name}}</h1>";
    });
    app.filter('unsafe', function ($sce) {
        return function(val) {
            return $sce.trustAsHtml(val);
       };
    });