Angular 指令:在隔离范围内使用 ng-model [英] Angular directive: using ng-model within isolate scope

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

问题描述

我不知道如何定义一个自定义指令:

  1. 使用隔离作用域,并且
  2. 在其模板的新范围内使用 ng-model 指令.

这是一个例子:

HTML:

<div ng-controller="ctrl"><dir model="foo.bar"></dir>外部指令:{{foo.bar}}

JS:

var app = angular.module('app',[]).controller('ctrl', function($scope){$scope.foo = { bar: 'baz' };}).directive('dir', function(){返回 {限制:'E',范围: {型号:'='},模板:'<div ng-if="true"><input type="text" ng-model="model"/><br/></div>'}});

此处所需的行为是通过指令的(隔离)作用域 model 属性将输入值绑定到外部作用域的 foo.bar 属性.这不会发生,因为模板的封闭 div 上的 ng-if 指令创建了一个新范围,所以更新的是该范围的 model,而不是指令的范围.通常你通过确保表达式中有一个点来解决这些 ng-model 问题,但我在这里看不到任何方法.我想知道我是否可以在我的指令中使用这样的东西:

<代码>{限制:'E',范围: {模型: {值:'=模型'}},模板:'<div ng-if="true"><input type="text" ng-model="model.value"/><br/></div>'}

但这不起作用...

Plunker

解决方案

你说得对 - ng-if 创建了一个子作用域,当在输入文本字段中输入文本时,它会导致问题.它在子作用域中创建了一个名为model"的影子属性,它是具有相同名称的父作用域变量的副本——有效地打破了双向模型绑定.

解决这个问题很简单.在您的模板中,指定 $parent 前缀:

 模板:'

<input type="text" ng-model="$parent.model"/><br/>

'

这确保它将从 $parent 作用域解析模型",您已经通过隔离作用域为双向模型绑定设置了该作用域.

最后,'.'在 ng-model 中节省了一天.我发现将点的任何剩余部分视为 Angular 通过范围继承解析属性的一种方式很有用.如果没有点,只有在分配范围变量时解析属性才会成为问题(否则,查找很好,包括只读 {{model}} 绑定表达式).

I'm having trouble working out how I can define a custom directive that both:

  1. Uses isolate scope, and
  2. Uses the ng-model directive in a new scope within in its template.

Here's an example:

HTML:

<body ng-app="app">
  <div ng-controller="ctrl">
    <dir model="foo.bar"></dir>
    Outside directive: {{foo.bar}}
  </div>
</body>

JS:

var app = angular.module('app',[])
  .controller('ctrl', function($scope){
    $scope.foo = { bar: 'baz' };
  })
  .directive('dir', function(){
    return {
      restrict: 'E',
      scope: {
        model: '='
      },
      template: '<div ng-if="true"><input type="text" ng-model="model" /><br/></div>'
    }
  });

The desired behaviour here is that the input's value is bound to the outer scope's foo.bar property, via the the directive's (isolate) scope model property. That doesn't happen, because the ng-if directive on the template's enclosing div creates a new scope, so it's that scope's model that gets updated, not the directive's scope's. Ordinarily you solve these ng-model issues by making sure there's a dot in the expression, but I can't see any way to do that here. I wondered if I might be able to use something like this for my directive:

{
  restrict: 'E',
  scope: {
    model: {
      value: '=model'
    }
  },
  template: '<div ng-if="true"><input type="text" ng-model="model.value" /><br/></div>'
}

but that doesn't work...

Plunker

解决方案

You are right - ng-if creates a child scope which is causing a problem when text is entered in the input text field. It creates a shadow property named 'model' in child scope which is a copy of the parent scope variable with the same name - effectively breaking the two-way model binding.

The fix for this is simple. In your template, specify the $parent prefix:

  template: '<div ng-if="true">
                   <input type="text" ng-model="$parent.model" /><br/>
             </div>'

This ensures that it will resolve 'model' from the $parent scope, which you've already setup for two-way model binding through the isolated scope.

In the end, the '.' in ng-model saves the day. I find it useful to think about anything left of the dot as a way for Angular to resolve the property through scope inheritance. Without the dot, resolving the property only becomes an issue when we're assigning scope variables (otherwise, lookups are fine, including read-only {{model}} binding expressions).

这篇关于Angular 指令:在隔离范围内使用 ng-model的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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