19

Say I have the following as part of my directive definition:

scope: {
    prop1: '@'
}

Is there any way for prop1 to get a default value if the directive doesn't have a prop1 attribute? Sure, I can check if it is defined myself and set it, but the property isn't always set when you would expect. I'm just wondering if there is any syntax I missed in the documentation, or if there is a good standard way of doing this. Thanks.

Community
  • 1
  • 1
dnc253
  • 39,967
  • 41
  • 141
  • 157

2 Answers2

19

It depends on what default value you want to assign. If you want to default to a name in the parent scope, setting a default attribute value in the directive's compile function will work:

  compile: function(element, attrs) {
    if (attrs.person == undefined) {
      attrs.$set("person", "person");
    }
  ...

If you want the directive to provide the default value, it gets a little tricker as Angular will not let you assign to the alias in the isolate scope (you will get a "Non-assignable model expression" exception from the watcher that's trying to propagate the assignment to the isolated parent scope). However you can prevent this by marking the attribute as optional (which means Angular won't register the listener when the property is ommited).

  scope: {
    person: "=?"
  },
  link: function(scope, element, attrs) {
    if (scope.person == undefined) {
      scope.person = "Bob";
    }
    ...
  }
Aardvark
  • 8,474
  • 7
  • 46
  • 64
Niall Smart
  • 848
  • 7
  • 10
  • 1
    I have never seen the `?` notation in the scope property before. Is there some place that is documented? Or a fiddle that shows that working? – dnc253 Aug 05 '13 at 14:39
  • https://github.com/angular/angular.js/commit/ac899d0da59157fa1c6429510791b6c3103d9401 – epeleg Mar 09 '14 at 07:43
  • 1
    Two things: 1) use `angular.isUndefined(...)` and 2) it's documented here: https://docs.angularjs.org/api/ng/service/$compile#directive-definition-object – icfantv Jul 16 '15 at 04:50
  • Interestingly (though disappointing), if `scope.person` has a value, it cannot be modified in the `link` method. Eg. `scope.classes = typeof(scope.classes) === 'string' ? scope.classes.split(' ') : scope.classes;`. It works within the `link` method, but gets overriden by the attribute at some point. – Augustin Riedinger Sep 09 '15 at 10:06
-3
scope['prop1'] = scope['prop1'] || '@'
Andy Hayden
  • 359,921
  • 101
  • 625
  • 535
ilan berci
  • 3,883
  • 1
  • 16
  • 21
  • I see that working in a general javascript sense, but this question is for when specifically defining a directive with AngularJS. I don't see how I could use this same concept there. – dnc253 Sep 28 '12 at 20:20
  • angular will throw an error if you try to do this syntax with the `?` optional flag. follow the solution above by @niall. – icfantv Jul 16 '15 at 04:53