iLemming
iLemming

Reputation: 36196

Directive with default data

I need to create a directive that has ng-repeat in its template, and that ng-repeat should either use something set in an attribute, or if attribute not present use "default array"

something like this:

app.directive 'myDir',->
  template:'<div> <h1 ng-repeat="d in data"> {{d}} </h1> </div>'
  scope:
     data:"="
  link: (scope, element, attrs)->
    unless attrs.data?
      $scope.data = [1..10]

except that doesn't really work, throwing "Non-Assignable Expression" error.

jsbin here

How do I make it work?

I could probably try using $parse but then I'm gonna have to re-compile the directive? What I want seems to be trivial, shouldn't be too difficult to make it work, right?

Upvotes: 1

Views: 54

Answers (2)

iLemming
iLemming

Reputation: 36196

Solved it doing this:

app.directive 'myDir',($parse)->
  restrict:'E'
  template:'<div> <h1 ng-repeat="d in data.headers"> {{d}} </h1> </div>'
  link: (scope, element, attrs)->
    scope.data = {}
    if attrs.headers?
      scope.data.headers = $parse(attrs.headers)(scope)
    else  
      scope.data.headers = [1..10]

But New Dev's solution is a lot better

Upvotes: 0

New Dev
New Dev

Reputation: 49590

From $compile documentation for "=":

If the parent scope property doesn't exist, it will throw a NON_ASSIGNABLE_MODEL_EXPRESSION exception. You can avoid this behavior using =? or =?attr in order to flag the property as optional.

You should set your scope to:

scope: {
   data: "=?"
}

OFF TOPIC: You can also cheaply define a default value right in the template:

template: '<div> <h1 ng-repeat="d in (data || [1, 2, 3])"> {{d}} </h1> </div>'

Upvotes: 1

Related Questions