简体   繁体   中英

Using dynamic layouts from json response: angularJS

In my web app, in a search result, each item can have a different look according to the type of item. To achieve this, I was thinking of including the layout with data placeholders for that particular item in the json response. How do I bind the scope data to the placeholders in the json response template?

for eg. My search result would look something like :

<li ng-repeat="item in items">
<div ng-bind-html="item.template"></div>
</li>

And the JSON response would look like :

[{
"template_name":"One",
"template":"<div ng-repeat='subitem in item.subitems'>{{subitem.name}}</div>",
"subitems":[{name:"John"},{name:"Jane"}]
},
{
"template_name":"Two",
"template":"<div ng-repeat='subitem in item.subitems'>{{subitem.name}}</div>",
"subitems":[{name:"John"},{name:"Jane"}]
}
]

Like you can see, I need to bind the placeholders in the json response with the scope data. Is there any way to do it? If not, how do you suggest i should address this situation?

Thank You!

While this will obviously not work:

<li ng-repeat="item in items">
  <div ng-bind-html="item.template"></div>
</li>

Since you are telling angular to display html that is inside item.template but what you really want is to tell it to treat item.template as it would be markup that should be parsed in a similar way to a template inside directive.

What you can do however is to define custom directive that will treat item.template in a desired manner. For instance:

<li ng-repeat="item in items">
  <div dynamic-template="item.template" />
</li>

Where dynamic-template is defined as follows:

 module.directive('dynamicTemplate', function($compile){
    return {
      scope: {
        dynamicTemplate:'='
      },
      replace:true,
      transclude: true,
      link: function($scope, $element, $attrs, _, $transcludeFn){
        // since we have isolate scope - transclude the element so it has access 
        // to item and anything else available inside ng-repeat
        $transcludeFn(function($childElement, $childScope){ 
          var link = $compile($scope.dynamicTemplate);
          var bound = link($childScope);
          $element.append(bound);
        });
      }
    };
  });

Of course this is not ideal since changes to item.template wont be reflected but you can easily extend this by adding $watch .

You can find working example here .

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