AngularJS - 创建一个使用 ng-model 的指令 [英] AngularJS - Create a directive that uses ng-model

查看:25
本文介绍了AngularJS - 创建一个使用 ng-model 的指令的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建一个指令,该指令将创建一个与创建指令的元素具有相同 ng-model 的输入字段.

I am trying to create a directive that would create an input field with the same ng-model as the element that creates the directive.

这是我目前想到的:

HTML

<!doctype html>
<html ng-app="plunker" >
<head>
  <meta charset="utf-8">
  <title>AngularJS Plunker</title>
  <link rel="stylesheet" href="style.css">
  <script>document.write("<base href=\"" + document.location + "\" />");</script>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.2/angular.js"></script>
  <script src="app.js"></script>
</head>
<body ng-controller="MainCtrl">
  This scope value <input ng-model="name">
  <my-directive ng-model="name"></my-directive>
</body>
</html>

JavaScript

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

app.controller('MainCtrl', function($scope) {
  $scope.name = "Felipe";
});

app.directive('myDirective', function($compile) {
  return {
    restrict: 'E',
    scope: {
      ngModel: '='
    },
    template: '<div class="some"><label for="{{id}}">{{label}}</label>' +
      '<input id="{{id}}" ng-model="value"></div>',
    replace: true,
    require: 'ngModel',
    link: function($scope, elem, attr, ctrl) {
      $scope.label = attr.ngModel;
      $scope.id = attr.ngModel;
      console.debug(attr.ngModel);
      console.debug($scope.$parent.$eval(attr.ngModel));
      var textField = $('input', elem).
        attr('ng-model', attr.ngModel).
        val($scope.$parent.$eval(attr.ngModel));

      $compile(textField)($scope.$parent);
    }
  };
});

但是,我不确定这是处理这种情况的正确方法,并且存在一个错误,即我的控件没有使用 ng-model 目标字段的值进行初始化.

However, I am not confident this is the right way to handle this scenario, and there is a bug that my control is not getting initialized with the value of the ng-model target field.

这是上面代码的一个 Plunker:http://plnkr.co/edit/IvrDbJ

Here's a Plunker of the code above: http://plnkr.co/edit/IvrDbJ

处理这个问题的正确方法是什么?

What's the correct way of handling this?

EDIT:从模板中删除 ng-model="value" 后,这似乎工作正常.但是,我会保留这个问题,因为我想仔细检查一下这是正确的做法.

EDIT: After removing the ng-model="value" from the template, this seems to be working fine. However, I will keep this question open because I want to double check this is the right way of doing this.

推荐答案

EDIT:此答案已过时且可能已过时.只是提醒一下,以免误导人们.我不再使用 Angular,因此我无法进行改进.

EDIT: This answer is old and likely out of date. Just a heads up so it doesn't lead folks astray. I no longer use Angular so I'm not in a good position to make improvements.

这实际上是很好的逻辑,但您可以稍微简化一下.

It's actually pretty good logic but you can simplify things a bit.

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

app.controller('MainCtrl', function($scope) {
  $scope.model = { name: 'World' };
  $scope.name = "Felipe";
});

app.directive('myDirective', function($compile) {
  return {
    restrict: 'AE', //attribute or element
    scope: {
      myDirectiveVar: '=',
     //bindAttr: '='
    },
    template: '<div class="some">' +
      '<input ng-model="myDirectiveVar"></div>',
    replace: true,
    //require: 'ngModel',
    link: function($scope, elem, attr, ctrl) {
      console.debug($scope);
      //var textField = $('input', elem).attr('ng-model', 'myDirectiveVar');
      // $compile(textField)($scope.$parent);
    }
  };
});

带有指令的HTML

<body ng-controller="MainCtrl">
  This scope value <input ng-model="name">
  <my-directive my-directive-var="name"></my-directive>
</body>

CSS

.some {
  border: 1px solid #cacaca;
  padding: 10px;
}

您可以通过这个 Plunker 看到它的实际效果.

You can see it in action with this Plunker.

这是我看到的:

  • 我理解您为什么要使用ng-model",但在您的情况下,这不是必需的.ng-model 是将现有 html 元素与范围内的值链接起来.由于您自己创建指令,因此您正在创建一个新"的 html 元素,因此您不需要 ng-model.
  • I understand why you want to use 'ng-model' but in your case it's not necessary. ng-model is to link existing html elements with a value in the scope. Since you're creating a directive yourself you're creating a 'new' html element, so you don't need ng-model.

编辑 正如马克在他的评论中提到的,没有理由你不能使用 ng-model,只是为了保持惯例.

EDIT As mentioned by Mark in his comment, there's no reason that you can't use ng-model, just to keep with convention.

  • 通过在您的指令中显式创建一个作用域(一个隔离"作用域),指令的作用域无法访问父作用域上的名称"变量(我认为这就是您想要使用 ng-model 的原因).
  • 我从您的指令中删除了 ngModel,并将其替换为一个您可以更改为任何名称的自定义名称.
  • 使这一切仍然有效的是范围中的="符号.查看范围"标题下的文档文档.

通常,如果您希望指令中的值始终映射到父作用域中的值,则您的指令应使用隔离范围(您做得对)并使用 '=' 类型范围.

In general, your directives should use the isolated scope (which you did correctly) and use the '=' type scope if you want a value in your directive to always map to a value in the parent scope.

这篇关于AngularJS - 创建一个使用 ng-model 的指令的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆