Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does AngularJS have a syntax to alias a property within a div?

This is kind of a weird question, but here's the idea:

Let's say I have a complex JSON object coming back from an HTTP call and attaching to the $scope. Something like this:

$scope.obj = {
    user: {
        id: 10,
        name: { first: 'Joe', last: 'Smith' },
        contact: {
            home: {
                street: '101 First St.',
                city: 'Myville',
                state: 'Jokelahoma',
                zip: '98765'
            },
            email: '[email protected]',
            phone: '+12345678901'
        }
    },
    purchase_hist: [
        { item_id: 11004, date: 'Thu, 06 Aug 2015 13:51:17 GMT' },
        { item_id: 97020, date: 'Fri, 31 Jul 2015 18:57:57 GMT' }
    ]
}

Now, if I wanted to display an overview of purchase history in an AngularJS partial, I could do something like this:

<table>
    <tr ng-repeat="p in obj.purchase_hist">
        <td>{{p.item_id}}</td>
        <td>{{p.date}}</td>
    </tr>
</table>

The really convenient thing about this format (though it's not super evident here with so few props) is that the purchase being described is aliased as p. I don't have to do obj.purchase_hist[0].item_id, I can just do p.item_id.

But what about when I go to show the user's home address? Do I really have to do this?:

<div>
    <p>{{obj.user.contact.home.street}}</p>
    <p>{{obj.user.contact.home.city}}</p>
    <p>{{obj.user.contact.home.state}}</p>
    <p>{{obj.user.contact.home.zip}}</p>
</div>

That's really verbose. I would much rather use something akin to the controller as ... syntax, something like this:

<div ng-alias="obj.user.contact.home as uhome">
    <p>{{uhome.street}}</p>
    <p>{{uhome.city}}</p>
    <p>{{uhome.state}}</p>
    <p>{{uhome.zip}}</p>
</div>

Is there such a thing that exists in AngularJS ? Unfortunately I'm not very able to use plugins in my environment, so I'm specifically looking for a part of angular core that will work this way.

Thanks!

like image 862
Ken Bellows Avatar asked Aug 06 '15 14:08

Ken Bellows


People also ask

What is $$ in AngularJS?

The $ in AngularJs is a built-in object.It contains application data and methods.

What is not recommended in AngularJS?

It is tempting to do too much work in the AngularJS controller. After all, the controller is where the view first has access to JavaScript via $scope functions. However, doing this will cause you to miss out on code sharing across the site and is not recommended by AngularJS documentation.

What does $scope mean in AngularJS?

$scope is a child object that is used to bind the HTML(view) & Javascript(Controller) in a webpage. It is created with the ng-app directive. It is created with the ng-controller directive. It is available globally for all the controllers, i.e, the property assigned with “$rootscope” can be used anywhere.

Which prefix is used with the AngularJS directives?

AngularJS directives are extended HTML attributes with the prefix ng- . The ng-app directive initializes an AngularJS application.


2 Answers

I've written this little directive, which allow you to perform what you want :

Directive ngAlias

(function(){

  function ngAlias($compile) {
    return {
        restrict: "A",
        link: function(scope, element, attrs) {
          var args = attrs.ngAlias.split('as').map(function(elm){return elm.replace(/ /g,'')});

          scope[args[0]] = '';

          var dot = args[1].split('.');

          var object = {};

          dot.forEach(function(value, index){
            index === 0
            ? object = scope[value]
            : object = object[value] === null ? object[value] = {} : object[value];
          });

          console.log(object)

          scope[args[0]] = object;
        }
    };
  }

angular
  .module('app')
  .directive('ngAlias', ngAlias);


})();

For example, set your object in your controller

Controller

(function(){

function Controller($scope) {


  $scope.obj = {
    toto: {
      nom: 'toto',
      prenom: 'tata'
    }
  };

}

angular
.module('app', [])
.controller('ctrl', Controller);

})();

And you can use it :

HTML

  <body ng-app="app" ng-controller="ctrl">

    <div ng-alias="toto as obj.toto">
      {{toto.nom}}
    </div>

  </body>
like image 182
Paul Boutes Avatar answered Nov 01 '22 06:11

Paul Boutes


@PaulBoutes provided the answer I needed, and he should get the credit; I just wanted to add the version of the directive that I settled on based on his answer.

app.directive('alias', function() {
    return {
        restrict: 'A',
        link: function(scope, element, attrs) {
            var splits = attrs['alias'].trim().split(/\s+as\s+/);
            scope.$watch(splits[0], function(val) {
                scope.$eval(splits[1]+'=('+splits[0]+')');
            });
        }
    };
});

Same basic idea as Paul's, just cleaned up a little and made a little more flexible in terms of whitespace and such.

Usage example:

<div data-alias="obj.user.contact.home as uhome">
    <p>{{uhome.street}}</p>
    <p>{{uhome.city}}</p>
    <p>{{uhome.state}}</p>
    <p>{{uhome.zip}}</p>
</div>
like image 22
Ken Bellows Avatar answered Nov 01 '22 05:11

Ken Bellows