CompareTheMooCat
CompareTheMooCat

Reputation: 1047

How to bind an object to a dom element in AngularJs

Guys I have some simple html, for illustration purposes say it looks like this,

<div>{{class.name}}</div>
<div>
    <div>{{class.teacher.name}}</div>
    <div>{{class.teacher.age}}</div>
    <div>{{class.teacher.rating}}</div>
</div>

now the model as you can see has a class object which has a name property and a teacher property. What I would like to do is avoid the duplication in this code so that my bindings look more like this.

<div>{{class.name}}</div>
<div some-directive-here="class.teacher">
    <div>{{name}}</div>
    <div>{{age}}</div>
    <div>{{rating}}</div>
</div>

Does angular support a directive where I can create a new scope for a dom element as shown above? I don't want to use ng-controller as it create a new scope and disconnects me from the original model data.

Upvotes: 3

Views: 3803

Answers (2)

Bart
Bart

Reputation: 61

An addition to the solution is consider async solutions. I have taken the plnkr example and updated the compile function and set the class-property after 2 seconds.

http://plnkr.co/edit/X8y3ArvTD3WDZIIB3qFk?p=preview

app.directive('newScope', function($parse){
  return {
    scope:true,
    compile: function (tElm,tAttrs){
      var init = false;
      var attr = tAttrs.newScope;
      var fn = $parse(attr);

      var linkFunction = function (scope, elm, attrs) {

        if (!init) {
          scope.$watch(attr, function (newValue, oldValue) {
            linkFunction(scope, elm, attrs);
          });
        }

        var property = fn(scope.$parent);
        property = angular.isObject(property) ? property : {};
        angular.extend(scope, property);

        init = true;

      };

      return linkFunction;    
    } 
  }
})

Upvotes: 0

Ilan Frumer
Ilan Frumer

Reputation: 32367

Here is a plunker: http://plnkr.co/edit/MqesLIUA1kq1S7BLal3N?p=preview

A simple directive which creates a new scope and extend it with the evaluated expression of it's parent scope.

Solution:

app.directive('newScope', function($parse){
  return {
    scope:true,
    compile: function (tElm,tAttrs){
      var fn = $parse(tAttrs.newScope);

      return function(scope, elm, attrs){
        var property = fn(scope.$parent);
        property = angular.isObject(property) ? property : {};
        angular.extend(scope, property);
      }      
    } 
  }
})

Upvotes: 1

Related Questions