0

I must be missing something but I can't figure out why this directive is not showing up, is there anyone to help?

<body ng-controller="MainCtrl">
<p>Test is <b>{{name}}</b> with myValue <b>{{myValue}}</b></p>
<my-new-directive my-test="{{myValue}}"></my-new-directive>
</body>

var app = angular.module('plunker', []);

app.controller('MainCtrl', function($scope) {
$scope.name = 'World';
$scope.myValue = true;
});


app.directive('myNewDirective', function() {
return {
 restrict: 'E',
 replace: true,
 link: function(scope, element, attrs) {
    attrs.$observe('myTest', function() {
    scope.name = attrs.myTest;
    if (!attrs.myTest) {
      this.template = '<div>FALSE</div>';
    } else {
      this.template = '<div>TRUE</div>';
    }
    scope.$apply();
  });
}
};
});

http://embed.plnkr.co/zijm24/preview

2 Answers 2

1

You shouldn't return template from the link function.

You can do this:

var app = angular.module('plunker', []);

app.controller('MainCtrl', function($scope) {
  $scope.name = 'World';
  $scope.myValue = true;
});


app.directive('myNewDirective', function() {
    return {
      restrict: 'E',
      replace: true,
      transclude: true,
      template: '<div>{{val}}</div>',
      link: function(scope, element, attrs) {
        attrs.$observe('myTest', function() {
          scope.name = attrs.myTest;
          if (!angular.fromJson(attrs.myTest)) {
            scope.val= 'FALSE';
          } else {
            scope.val= 'TRUE';
          }
          scope.$apply();
        });
      }
    };
  });
Sign up to request clarification or add additional context in comments.

9 Comments

Now, I'm trying to do something similar with templateUrl but myValue would be the result of a service call. Any idea how I can achieve that? Need an Angular for dummies course sure :-(
For templateUrl you just replace the template attribute with templateUrl attribute: templateUrl: 'template.html' As for the service, once you have a service that return a value, and you update myValue on the scope, the template acts accordingly. You don't need to change the directive implementation at all.
I strongly recommend egghead lessons: egghead.io/articles/new-to-angularjs-start-learning-here
Well, nope :-( does not work with templateUrl plnkr.co/edit/zijm24?p=preview
No, it doesn't work that way. You can't use curly brackets for templateUrl. You should point to a predefined html, and in that html you should put the content that you had in your template ('<div>{{val}}</div>'). If you really insist on dynamically load different html according to scope values, I'm almost sure I have somewhere example for it, but first you have to convince yourself that you really need it...
|
1

I would reduce this to this code:

<body ng-controller="MainCtrl">
    <p>Test is <b>{{name}}</b> with myValue <b>{{myValue}}</b></p>
    <label><input type="checkbox" ng-model="myValue"> myValue</label>
    <my-new-directive my-test="myValue"></my-new-directive>
</body>

Note that in the above HTML, my-test receives the model directly, not an expression. Also, I added a demo consisting of a checkbox so you can toggle the value.

Then, the JS would look like this for what you seem to need:

app.directive('myNewDirective', function() {
    return {
        restrict: 'E',
        scope: {
            name: '=myTest'
        },
        template: '<div>{{ name }}</div>'
    };
});

So basically, I removed transclusion, since you didn't use it (re-add if needed) and introduced a two-way bound isolate scope instead of manually adding the logic for observing the value of the parent scope's model. This lets you get rid of the linking function completely - at least until you need to add extra functionality.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.