1

I am playing around in Ionic and would like to insert custom html into the view, that would also have directives such as ng-if, is that possible?

Example: I'd like to have a service that displays a dialog window with custom text anywhere in the app = it would just inject it into the view when needed.

Currently I have <div ng-bind-html="dialogWindow"></div> in my sidemenu from the Ionic template as that is an abstract state and the controller + view is accessible everywhere.

Then I have this in the main controller - $rootScope.dialogWindow = '';

And the services

angular.module('starter.services')
.factory('$dialogs', ['$htmlInjector', function ($htmlInjector) {
    return {
        show: function (type) {

            if (type === 'type_a') {

                var template = '' +
                    '<div class="overlay" ng-if="condition" ng-click="doSomething()"></div>' +
                    '<div class="dialog">Test Controller</b>' +
                '';

                $htmlInjector.add(template, 'dialog');
            }

        }
    }
}]);

and then

angular.module('starter.services')
.factory('$htmlInjector', ['$rootScope', function ($rootScope) {
    return {
        add: function (html, element) {

            if (element === 'dialog') {
                $rootScope.dialogWindow = html;
            }

        }
    }
}]);

So this works so far but the template gets sanitised if that's the right term and so no directives are available :( What is a better way of doing this? My idea is to inject the html node only when needed and into any view, not just in the main one ( I am doing that because that way i can display the dialog on any screen page).

Thanks

1 Answer 1

2

I actually had this very same problem with a website generator I was playing with before. Use compile instead of ng-bind-html. I found this piece of code that did the trick:

angular.module('clientApp').config(function($compileProvider) {
    // configure new 'compile' directive by passing a directive
    // factory function. The factory function injects the '$compile'
    $compileProvider.directive('compile', function($compile) {
      // directive factory creates a link function
      return function(scope, element, attrs) {
        scope.$watch(
          function(scope) {
             // watch the 'compile' expression for changes
            return scope.$eval(attrs.compile);
          },
          function(value) {
            // when the 'compile' expression changes
            // assign it into the current DOM
            element.html(value);

            // compile the new DOM and link it to the current
            // scope.
            // NOTE: we only compile .childNodes so that
            // we don't get into infinite loop compiling ourselves
            $compile(element.contents())(scope);
          }
        );
      };
    });
  });

The above code adds a compile directive that can be used instead of ng-bind-html from within the template.

So instead of using <div ng-bind-html="dialogWindow"></div> you would end up using <div compile="dialogWindow"></div>

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you, looks promising and makes sense, I will try it when I have next time, any suggestions for actually injecting the node into the view? I searched around, is jqLite the way to go? I feel very dirty for using that method I'm using right now, it should be only a temp solution

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.