如何在自定义指令中获取评估的属性 [英] How to get evaluated attributes inside a custom directive

查看:28
本文介绍了如何在自定义指令中获取评估的属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试从我的自定义指令中获取一个 评估 属性,但我找不到正确的方法.

我创建了这个jsFiddle来详细说明.

<input my-directive value="123"><input my-directive value="{{1+1}}">

myApp.directive('myDirective', function () {返回函数(范围,元素,属性){element.val("value = "+attr.value);}});

我错过了什么?

解决方案

注意:我会在找到更好的解决方案时更新此答案.只要它们仍然相关,我也会保留旧答案以供将来参考.最新和最好的答案在前.

更好的答案:

angularjs 中的指令非常强大,但需要时间来理解它们背后的进程.

在创建指令时,angularjs 允许您创建一个独立作用域,并绑定到父作用域.这些绑定由您在 DOM 中附加元素的属性以及您在指令定义对象中定义范围属性的方式指定.

您可以在范围内定义 3 种类型的绑定选项,并将它们写为与前缀相关的属性.

angular.module("myApp", []).directive("myDirective", function () {返回 {限制:A",范围: {文本:@myText",twoWayBind: "=myTwoWayBind",oneWayBind:&myOneWayBind"}};}).controller("myController", function ($scope) {$scope.foo = {name: "Umur"};$scope.bar = "qwe";});

HTML

<div my-directive my-text="hello {{ bar }}";my-two-way-bind="foo";my-one-way-bind="bar">

在这种情况下,在指令范围内(无论是链接函数还是控制器),我们可以像这样访问这些属性:

/* 指令范围 */在:$scope.text出:你好qwe"//这将自动更新摘要中值的变化//这始终是字符串,因为 dom 属性值始终是字符串在:$scope.twoWayBind出:{名称:Umur"}//这将自动更新摘要中值的变化//this 中的更改将反映在父作用域中//在指令的范围内在:$scope.twoWayBind.name =约翰";//在父作用域在:$scope.foo.name出:约翰"in: $scope.oneWayBind()//注意函数调用,这个绑定是只读的出:qwe"//此处的任何更改都不会反映在父级中,因为这只是一个 getter .

还可以"答案:

既然这个答案被接受了,但有一些问题,我会把它更新成更好的.显然,$parse 是一个不属于当前作用域属性的服务,这意味着它只需要角度表达式,不能到达作用域.{{,}} 表达式在 angularjs 启动时被编译,这意味着当我们尝试在我们的指令 postlink 方法中访问它们时,它们已经被编译.({{1+1}} 在指令中已经是 2 了).

这是您希望使用的方式:

var myApp = angular.module('myApp',[]);myApp.directive('myDirective', function ($parse) {返回函数(范围,元素,属性){element.val("value=" + $parse(attr.myDirective)(scope));};});函数 MyCtrl($scope) {$scope.aaa = 3432;}

.

<input my-directive="123"><输入我的指令=1+1"><input my-directive="'1+1'"><input my-directive="aaa"></div>

这里你应该注意的一件事是,如果你想设置值字符串,你应该把它用引号括起来.(见第三个输入)

这是要玩的小提琴:http://jsfiddle.net/neuTA/6/

旧答案:

对于像我这样可能被误导的人,我不会删除它,请注意,使用 $eval 是完全正确的方法,但是 $parse 具有不同的行为,您可能不需要在大多数情况下使用它.

再次使用 scope.$eval 的方法是.它不仅可以编译角度表达式,还可以访问当前作用域的属性.

var myApp = angular.module('myApp',[]);myApp.directive('myDirective', function () {返回函数(范围,元素,属性){element.val("value = "+ scope.$eval(attr.value));}});函数 MyCtrl($scope) {}

你缺少的是$eval.

<块引用>

http://docs.angularjs.org/api/ng.$rootScope.Scope#$eval

在当前作用域上执行表达式,返回结果.表达式中的任何异常都会传播(未捕获).这在评估角度表达式时很有用.

I'm trying to get an evaluated attribute from my custom directive, but I can't find the right way of doing it.

I've created this jsFiddle to elaborate.

<div ng-controller="MyCtrl">
    <input my-directive value="123">
    <input my-directive value="{{1+1}}">
</div>

myApp.directive('myDirective', function () {
    return function (scope, element, attr) {
        element.val("value = "+attr.value);
    }
});

What am I missing?

解决方案

Notice: I do update this answer as I find better solutions. I also keep the old answers for future reference as long as they remain related. Latest and best answer comes first.

Better answer:

Directives in angularjs are very powerful, but it takes time to comprehend which processes lie behind them.

While creating directives, angularjs allows you to create an isolated scope with some bindings to the parent scope. These bindings are specified by the attribute you attach the element in DOM and how you define scope property in the directive definition object.

There are 3 types of binding options which you can define in scope and you write those as prefixes related attribute.

angular.module("myApp", []).directive("myDirective", function () {
    return {
        restrict: "A",
        scope: {
            text: "@myText",
            twoWayBind: "=myTwoWayBind",
            oneWayBind: "&myOneWayBind"
        }
    };
}).controller("myController", function ($scope) {
    $scope.foo = {name: "Umur"};
    $scope.bar = "qwe";
});

HTML

<div ng-controller="myController">
    <div my-directive my-text="hello {{ bar }}" my-two-way-bind="foo" my-one-way-bind="bar">
    </div>
</div>

In that case, in the scope of directive (whether it's in linking function or controller), we can access these properties like this:

/* Directive scope */

in: $scope.text
out: "hello qwe"
// this would automatically update the changes of value in digest
// this is always string as dom attributes values are always strings

in: $scope.twoWayBind
out: {name:"Umur"}
// this would automatically update the changes of value in digest
// changes in this will be reflected in parent scope

// in directive's scope
in: $scope.twoWayBind.name = "John"

//in parent scope
in: $scope.foo.name
out: "John"


in: $scope.oneWayBind() // notice the function call, this binding is read only
out: "qwe"
// any changes here will not reflect in parent, as this only a getter .

"Still OK" Answer:

Since this answer got accepted, but has some issues, I'm going to update it to a better one. Apparently, $parse is a service which does not lie in properties of the current scope, which means it only takes angular expressions and cannot reach scope. {{,}} expressions are compiled while angularjs initiating which means when we try to access them in our directives postlink method, they are already compiled. ({{1+1}} is 2 in directive already).

This is how you would want to use:

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

myApp.directive('myDirective', function ($parse) {
    return function (scope, element, attr) {
        element.val("value=" + $parse(attr.myDirective)(scope));
    };
});

function MyCtrl($scope) {
    $scope.aaa = 3432;
}​

.

<div ng-controller="MyCtrl">
    <input my-directive="123">
    <input my-directive="1+1">
    <input my-directive="'1+1'">
    <input my-directive="aaa">
</div>​​​​​​​​

One thing you should notice here is that, if you want set the value string, you should wrap it in quotes. (See 3rd input)

Here is the fiddle to play with: http://jsfiddle.net/neuTA/6/

Old Answer:

I'm not removing this for folks who can be misled like me, note that using $eval is perfectly fine the correct way to do it, but $parse has a different behavior, you probably won't need this to use in most of the cases.

The way to do it is, once again, using scope.$eval. Not only it compiles the angular expression, it has also access to the current scope's properties.

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

myApp.directive('myDirective', function () {
    return function (scope, element, attr) {
        element.val("value = "+ scope.$eval(attr.value));
    }
});

function MyCtrl($scope) {
   
}​

What you are missing was $eval.

http://docs.angularjs.org/api/ng.$rootScope.Scope#$eval

Executes the expression on the current scope returning the result. Any exceptions in the expression are propagated (uncaught). This is useful when evaluating angular expressions.

这篇关于如何在自定义指令中获取评估的属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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