简体   繁体   English

用angularjs中的指令模板

[英]templating with directives in angularjs

I'm trying to figure out where and how to use directives in angularjs. 我试图弄清楚在angularjs中在哪里以及如何使用指令。 I have several pages with lots of input fields and each time I want to add some conditional ng-class and a button that only shows in certain conditions. 我有几个页面,其中包含很多输入字段,每次我想添加一些条件ng-class和一个仅在特定条件下显示的按钮。 A rough example can be seen at: 可以在以下位置看到一个粗略的示例:

JSFiddle without directives 没有指令的JSFiddle

Now I'd like to type less and hope that directives can help me. 现在,我希望减少键入,并希望指令可以为我提供帮助。 The following code does not work, but maybe it shows where I want to go: 以下代码不起作用,但也许显示了我想去的地方:

this is how I'd like to type my html: 这就是我想要输入html的方式:

  <tr>
    <td>First Name:</td>
    <td>
        <dirty-input attr="firstName"/>
    </td>
  </tr>
  <tr>
    <td>Last Name:</td>
    <td>
        <dirty-input attr="lastName"/>
    </td>
  </tr>

so I tried to accomplish this with following controller: 因此,我尝试使用以下控制器来实现此目的:

app.controller('PersonController', function($scope) {
    $scope.person = {firstName: 'John', lastName: 'Doe'};
    $scope.personEdited = {firstName: $scope.person.firstName, lastName: $scope.person.lastName};
    $scope.firstName = {objName: 'person', editedObject: 'personEdited', attrName: 'firstName'};
    $scope.lastName = {objName: 'person', editedObject: 'personEdited', attrName: 'lastName'};
});

and this directive: 和此指令:

app.directive('dirtyInput', function() {
    return {
        restrict: 'E',
        scope: {
            attr: '=attr',
        },
        template: '<input type="text" ng-model="{{attr.editedObject}}.{{attr.attrName}}"/>'
    };
});

This can be seen at: JSFiddle with directives (not working) 可以在以下位置看到: 带指令的JSFiddle(不起作用)

Obviously, this doesn't work. 显然,这是行不通的。 Am I trying to do something that isn't possible or am I just doing it wrong? 我是在尝试做一些不可能的事情,还是我做错了?

You were pretty close ! 你很亲密!

A couple of things that need to change: 需要更改的几件事:

  1. On ngModel you have to refer to a property in the scope. ngModel您必须在范围内引用属性。
    Instead of: ng-model="{{attr.editedObject}}.{{attr.attrName}} 而不是: ng-model="{{attr.editedObject}}.{{attr.attrName}}
    You should have something like: ng-model="attr.editedObject[attr.attrName] 您应该具有以下内容: ng-model="attr.editedObject[attr.attrName]
    (which means: "Bind to the property named x of the object referenced by the 'editedObject' property of the object referenced by scope's attr property. Where x is the property whose name equals the value of attr 's 'attrName' property.") (意思是:“来绑定范围的引用名为x的对象的‘editedObject’属性引用的对象的属性attr属性其中x是他的名字等同价值的财产。 attr的‘attrName’属性”。 )
    Yeah, whatever ! 好吧,无所谓了 !

  2. In order for the isolate scope to get access to the actually edited object (ie personEdited ), it needs a reference to it. 为了使隔离范围能够访问实际编辑的对象(即personEdited ),它需要对其进行引用。 There are a couple of ways to achieve this, but I think the easiest would be to put a reference to it inside the firstname , lastname objects. 有两种方法可以实现此目的,但我认为最简单的方法是在firstnamelastname对象中放置对它的引用。 Eg: 例如:
    Instead of: $scope.firstName = {...editedObject: 'personEdited',...} 而不是: $scope.firstName = {...editedObject: 'personEdited',...}
    Use: $scope.firstName = {...editedObject: $scope.personEdited,...} 使用: $scope.firstName = {...editedObject: $scope.personEdited,...}

See, also, this short demo . 另请参见此简短演示

You are misunderstanding how the isolate scope works. 您误解了隔离范围的工作原理。 Your directive's template is trying to access {{attr.editedObject}}.{{attr.attrName}} on its isolate scope. 指令的模板正在尝试在其隔离范围内访问{{attr.editedObject}}.{{attr.attrName}} Let's suppose angular resolves {{attr.editedObject}}.{{attr.attrName}} to personEdited.firstName . 假设将{{attr.editedObject}}.{{attr.attrName}} personEdited.firstNamepersonEdited.firstName Now consider the isolate scope, which currently consists of a single property, attr . 现在考虑隔离范围,该范围当前由单个属性attr When your directive resolves personEdited.firstName , it looks in its isolate scope, and only sees attr . 当您的指令解析personEdited.firstName ,它将查找其隔离范围,并且仅看到attr Because personEdited is undefined, nothing happens. 因为personEdited是未定义的,所以什么也不会发生。 In order for this to work, you would have to include another property in your isolate scope that was assigned the value of personEdited on your controllers scope. 为了使它起作用,您必须在隔离范围中包括另一个属性,该属性在控制器范围内被分配了personEdited的值。 That property will need to be named personEdited : 该属性将需要命名为personEdited

scope: {
  attr: '=attr',
  personEdited: '=personEdited'
}

And then you need to assign it in your directive usage: 然后需要在指令用法中分配它:

<dirty-input attr="firstName" personEdited="personEdited" />

Now your isolate scope will have access to your personEdited object defined in your PersonController . 现在,您的分离范围将有机会获得您的personEdited在你定义的对象PersonController Hope this helps. 希望这可以帮助。

edit 编辑

After thinking about this for a bit, you might want to try a controller within a directive. 考虑了一下之后,您可能想尝试使用指令中的控制器。 From what I am guessing based on your question, what you really want is access to the scope of PersonController . 根据您的问题,根据我的猜测,您真正想要的是访问PersonController的范围。 You can accomplish this using the following syntax in your directive: 您可以在指令中使用以下语法来完成此操作:

myApp.directive('myDirtyInput', function () {
  return {
    restrict: 'E',
    replace: true,
    templateUrl: 'DirtyInput.html',
    controller: '@',
    name: 'ctrl'
  };
});

The two pieces to note here are the controller property and the name property. 这里要注意的两个部分是controller属性和name属性。 What these are telling angular js is that we are going to allow the user of our directive to bind a controller for us to use, and it will be assigned by defining the ctrl attribute on the directive declaration. 这些告诉angular js的是,我们将允许指令的用户绑定控制器供我们使用,并且将通过在指令声明中定义ctrl属性来对其进行分配。 So in our case this will look like: 因此,在我们的例子中,它看起来像:

<my-dirty-input ctrl="PersonController"></my-dirty-input>

Now, with our controller bound to our directive, we have full access to our controllers scope from within the directive. 现在,将控制器绑定到指令之后,我们就可以从指令中完全访问我们的控制器范围。 We don't have to create an isolate scope, we can simply start accessing our controller's properties. 我们不必创建隔离范围,只需开始访问控制器的属性即可。

Here is a plunker with an example of what I guessed you were aiming to do (based on the fiddle you posted): http://plnkr.co/edit/4AQkCSIJvqsrUOBOqway?p=preview 这是一个矮人,上面有一个我猜想您打算做的事的例子(基于您发布的小提琴): http ://plnkr.co/edit/4AQkCSIJvqsrUOBOqway?p=preview

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM