javascript - AngularJS Directive - dynamic input name binding - Stack Overflow

I am attempting to learn a little more about AngularJS' directives and have run into this situatio

I am attempting to learn a little more about AngularJS' directives and have run into this situation. I would like to make a yes-no radio control that I can reuse. I have gotten most of the way - I think - but need a little push in the right direction.

I have this directive:

app
  .directive('yesno', function () {
    'use strict';

    var config;

    config = {
      replace: true,
      require: 'ngModel',
      restrict: 'E',
      scope: {
        field: '=',
        model: '='
      },
      templateUrl: 'views/yesno.html'
    };

    return config;
  });

...and the template looks like this:

<fieldset class="yesno">
  <input id="{{field}}-yes" name="{{field}}" ng-model="model" type="radio" value="yes" />
  <label for="{{field}}-yes">Yes</label>
  <input id="{{field}}-no" name="{{field}}" ng-model="model" type="radio" value="no" />
  <label for="{{field}}-no">No</label>
</fieldset>

...and I am using it like this (simplified):

<form name="person">
  <yesno field="'happy'" model="happy" />
</form>

Unfortunately what I am getting in the person object is a property {{field}} instead of happy like I would like. I keep telling myself that something like what I am attempting is possible and I just need to find it; but what.

Help please.

Update

Thank you, @HackedByChinese that helped a little but still not quite there. The problem is that I do want two way binding so that the value of the radios is populated into the parent scope; instead, when I inspect the person object it has a {{field}} property and not a happy property.

I am thinking that this is just something that AngularJS does not support in looking at:

AngularJS: Fields added dynamically are not registered on FormController

...and:

.js/issues/1404

I am attempting to learn a little more about AngularJS' directives and have run into this situation. I would like to make a yes-no radio control that I can reuse. I have gotten most of the way - I think - but need a little push in the right direction.

I have this directive:

app
  .directive('yesno', function () {
    'use strict';

    var config;

    config = {
      replace: true,
      require: 'ngModel',
      restrict: 'E',
      scope: {
        field: '=',
        model: '='
      },
      templateUrl: 'views/yesno.html'
    };

    return config;
  });

...and the template looks like this:

<fieldset class="yesno">
  <input id="{{field}}-yes" name="{{field}}" ng-model="model" type="radio" value="yes" />
  <label for="{{field}}-yes">Yes</label>
  <input id="{{field}}-no" name="{{field}}" ng-model="model" type="radio" value="no" />
  <label for="{{field}}-no">No</label>
</fieldset>

...and I am using it like this (simplified):

<form name="person">
  <yesno field="'happy'" model="happy" />
</form>

Unfortunately what I am getting in the person object is a property {{field}} instead of happy like I would like. I keep telling myself that something like what I am attempting is possible and I just need to find it; but what.

Help please.

Update

Thank you, @HackedByChinese that helped a little but still not quite there. The problem is that I do want two way binding so that the value of the radios is populated into the parent scope; instead, when I inspect the person object it has a {{field}} property and not a happy property.

I am thinking that this is just something that AngularJS does not support in looking at:

AngularJS: Fields added dynamically are not registered on FormController

...and:

https://github./angular/angular.js/issues/1404

Share Improve this question edited May 23, 2017 at 12:12 CommunityBot 11 silver badge asked Jan 24, 2014 at 3:01 kalisjoshuakalisjoshua 2,5063 gold badges28 silver badges37 bronze badges 3
  • I am learning - have learned - that there is more than one thing involved with this; the scope, which holds the values, and the validation object, which holds the results of the various rules for the form. I am noticing that the scope is working fine. However, the validation object is not dynamically bound; it has a property named using the unresolved view contents and is what I am referring to in the Update above. – kalisjoshua Commented Jan 26, 2014 at 0:03
  • This should work for you [stackoverflow link][1] [1]: stackoverflow./questions/27071413/… – SoEzPz Commented Nov 21, 2014 at 22:40
  • Go here stackoverflow./questions/27071413/… – SoEzPz Commented Nov 21, 2014 at 22:41
Add a ment  | 

2 Answers 2

Reset to default 3

Well if you just want field to contain the string value that was entered, you can use the @ prefix for the attribute to indicate it is a text binding (it will interpret the value of the attribute as literal text).

  scope: {
    field: '@',
    model: '='
  },

Click for demo.

On the other hand, if you need field to bind to the value an expression provided to the attribute (for example, you want to bind to a property on the parent scope), then you need to change the template HTML to evaluate field (simply {{field()}}) because they will be functions. The difference here is if people want to provide string values directly, they'll need to put it in quotes like your original example. I would also remend a one-way binding, since it seems unlikely your directive would want to modify the parent scope value since it's just a name. Use the & prefix for that.

  scope: {
    field: '&',
    model: '='
  },

<fieldset class="yesno">
  <input id="{{field()}}-yes" name="{{field()}}" ng-model="model" type="radio" value="yes" />
  <label for="{{field()}}-yes">Yes</label>
  <input id="{{field()}}-no" name="{{field()}}" ng-model="model" type="radio" value="no" />
  <label for="{{field()}}-no">No</label>
</fieldset>

Click for second demo.

I ran into the same problem. The simplest solution is to inject the name value directly into the template string.

It works as long as you don't need the name value to be bound (ie. it doesn't need to change during the lifetime of the directive). Considering the way the name attribute is usually used, I think this constraint is not an problem.

app
  .directive('yesno', function () {
    return {
      replace: true,
      restrict: 'E',
      scope: {
        field: '@',
        model: '='
      },
      template: function(element, attrs) {
        return '<fieldset class="yesno"> \
          <input id="{{field}}-yes" name="{{field}}" ng-model="model" type="radio" value="yes" /> \
           <label for="{{field}}-yes">Yes</label> \
           <input id="{{field}}-no" name="{{field}}" ng-model="model" type="radio" value="no" /> \
           <label for="{{field}}-no">No</label> \
           </fieldset>'.replace('{{field}}', attrs.field, 'g');
      }
    };
});

This solution is a bit messy, because of the inline html. If you want to load the template from a file as in the original question, you can do it like this:

app
  .directive('yesno', ['$http', '$templateCache', '$pile',
  function ($http, $templateCache, $pile) {
    return {
      restrict: 'E',
      scope: {
        field: '@',
        model: '='
      },
      link: function(scope, element) {
        $http.get('views/yesno.html', {cache:$templateCache})
          .then(function(response) {
            var content = angular.element(response.data.replace('{{field}}', scope.field, 'g'));
            element.append(content);
            $pile(content)(scope);
          });
      }
    };
}]);

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745441969a4627869.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信