当我更改任何选择时,指令不会监听$ watch

时间:2014-03-14 17:38:41

标签: javascript angularjs

我在Angular中创建了这个指令:

app.directive('country', ['$http', function($http) {
        return {
            restrict: "C",
            link: function(scope, element, attrs) {
                $http.get(Routing.generate('countries')).success(function(data) {
                    if (data.message) {
                        scope.message = data.message;
                    } else {
                        scope.countries = data.entities;
                    }
                }).error(function(data, status, headers, config) {
                    if (status == '500') {
                        scope.message = "No hay conexión con el servidor.";
                    }
                });
            }
        };
    }]);

app.directive('state', ['$http', function($http) {
        return {
            restrict: "C",
            link: function(scope, element, attrs) {
                scope.$watch(attrs.trigger, function(selectedType) {
                    if (eval('scope.' + attrs.trigger) !== undefined) {
                        states = eval('scope.' + attrs.statetrigger);
                        states = {};

                        $http.get(Routing.generate('states') + '/' + eval('scope.' + attrs.trigger).iso_country).success(function(data) {
                            if (data.message) {
                                scope.message = data.message;
                            } else {
                                scope.states = data.entities;
                            }
                        }).error(function(data, status, headers, config) {
                            if (status == '500') {
                                scope.message = "No hay conexión con el servidor.";
                            }
                        });
                    }
                });
            }
        };
    }]);

这是相关的HTML代码:

<select class="country"
        ng-model = "country"
        ng-options = "country.iso_country as country.name for country in countries"
        tooltip = ""
        tooltip-trigger = "focus"
        tooltip-placement = "right"
        wv-cur = ""
        wv-err = "Error!"
        wv-req = "The value you selected is not a valid choice"
        type = "text">
    <option value="">{{ "Select country" | trans }}</option>
</select>

<select class="state"
        ng-model = "state"
        ng-disabled = "!states"
        ng-options = "state.iso as state.name for state in states"
        tooltip-trigger = "focus"
        tooltip-placement = "right"
        wv-cur = ""
        wv-err = "Error!"
        wv-req = "The value you selected is not a valid choice"
        type = "text"
        trigger = "country">
    <option value="">{{ "Select state" | trans }}</option>
</select>

这背后的想法是:当我改变任何国家时,我应该使用来自第二个指令的新值来填充states,但是$watch没有正在侦听,因为第二个选择永远不会被填充,我的错误在哪里?

2 个答案:

答案 0 :(得分:2)

$scope是一个特殊的注入对象,只能供控制器使用。

您可以引用$rootScope,但这是不明智的,除非您构建的服务或指令非常通用/全局。

<强>更新

您正在尝试将原始eval用于特定于Angular的内容。您确实想使用$parse function来提取scope

中的值
var accessor = $parse(attrs.trigger);
var value = accessor(scope);

更新2:

我重新创建了一个ver slimmed down version of your code using jsFiddle并且发现它运行正常。您必须单步执行代码才能找出问题所在,因为显然我们无法看到错误。

答案 1 :(得分:1)

我认为你误解了Angular中Scope的使用。

Scope是DOM-Tree和JS之间的链接。因此,Scope在DOM的“区域”(也称为元素及其子节点)内始终有效。那么Angular需要知道的是你想要应用那个范围。在一个指令中,这显然是指令模板或更精确:指定定义的元素。因此,在您的链接功能中,您拥有scope - 变量。

另一方面,$scope - 变量是控制器的范围 - 通过在Dom中使用ng-controller设置Controller来明确定义的范围。

长话短说:在指令中注入$scope没有任何意义,因为Angular不知道它属于哪个DOM。

如果您想从指令中访问控制器$scope,您可以尝试使用scope.$parent或使用服务来共享数据。