【问题标题】:Angularjs ng-model not working after defining the ng-model in a directive在指令中定义 ng-model 后,Angularjs ng-model 不起作用
【发布时间】:2017-03-03 19:42:27
【问题描述】:

我希望根据输入的名称自动创建输入的 ng-model。这是因为 MVC 中的 Html.TextBoxFor 等创建了正确的名称来将输入绑定到服务器端模型。为了减少用户必须在 ng-model 中重新键入确切的字符串而导致的错误,我希望我的团队只需放置一个指令并创建它。我在stackoverflow上找到了这段代码。

datatableApp.directive('automaticangularmodelbinding', function ($compile) {
            return {
                restrict: 'A',
                replace: false,
                priority: 10000,
                terminal: true, // these terminal and a high priority will stop all other directive from being compiled at first run,
                scope: {
                    automaticangularmodelbinding: '@@'
                },
                link: function (scope, element, attrs) {                    
                    attrs.$set('ngModel', (scope.automaticangularmodelbinding != '') ? (scope.automaticangularmodelbinding + '.' + attrs.name) : attrs.name); // set value of ng-model to be the same as the name attribute
                    attrs.$set('automaticangularmodelbinding', null); // remove itself to avoid a recusion

                    $compile(element)(scope); // begin compiling other directives
                }
            };
        });

这是可行的,并且 ng-model 是使用元素的名称创建的。但是,当我从服务器中提取数据并进行设置时,输入不会被数据填充。如果我取出自动指令并通过 ng-model 正常定义它,它确实有效。

我的服务器代码下拉。

$scope.getEditStreet = function (streetID) {
                $http.post('@Url.Action(Model.GetFormControllerFunctionName, Model.GetFormControllerName)', "{ @Model.JavascriptEditPropertyName : " + streetID + "}").then(function (response) {                    
                    $scope.editFormData = response.data.ResultObject;
                    $scope.$apply();                        
                }, function (response) {
                    alert("fail" + response.statusText);
                });
            };

使用 ng-model,我需要调用 scope.apply 来检查复选框。使用此自动版本后,scope.apply 出现错误。如果我删除范围 apply 虽然它仍然无法在文本框上工作,即使之前没有应用也可以工作。

这似乎是我在事后添加了 ng-model 的事实,它的工作方式与从一开始就存在的方式不同。我怎样才能让它工作?

编辑:

阅读zaitsman cmets后,最终生效的版本如下。我从指令中删除了范围,并使用 attrs['automaticangularmodelbinding'] 来传递我需要的数据。

datatableApp.directive('automaticangularmodelbinding', function ($compile) {
            return {
                restrict: 'A',
                replace: false,
                priority: 10000,
                terminal: true, // these terminal and a high priority will stop all other directive from being compiled at first run,
                link: function (scope, element, attrs) {                    
                    attrs.$set('ngModel', (attrs['automaticangularmodelbinding'] != '') ? (attrs['automaticangularmodelbinding'] + '.' + attrs.name) : attrs.name); // set value of ng-model to be the same as the name attribute
                    attrs.$set('automaticangularmodelbinding', null); // remove itself to avoid a recusion

                    $compile(element)(scope); // begin compiling other directives
                }
            };
        });

【问题讨论】:

  • 您的指令声明了隔离范围,因为您指定了scope。在这种情况下,当您执行 getEditStreet 时,它会将 editFormData 设置在其他范围内,因为它无法访问指令的范围。你真的需要为你的指令隔离范围吗?
  • @zaitsman 不,我不需要隔离范围。我认为这是允许我在调用中添加变量的语法。我希望能够说 和
    。通过放入范围,我能够做到这一点(传入一个可选字符串)。如果这打破了它,也许我不能有额外的参数?
  • mate 参数与孤立作用域完全无关。假设您将scope 从directive 中剔除,那么在link 函数中,您可以执行var myPara = scope[attrs['automaticangularmodelbinding']];,它将包含来自父作用域的extraParameterInFront。如果 parameter 只是一个字符串,那就更简单了:var myPara = attrs['automaticangularmodelbinding'];
  • @zaitsman 使用 attrs['automaticangularmodelbinding'] 效果很好,现在一切正常。如果您发布作为答案,我会接受。谢谢。
  • 添加了答案,谢谢!

标签: javascript angularjs asp.net-mvc razor


【解决方案1】:

如前所述,我建议您跳过独立作用域,以便可以使用指令声明作用域中的变量。 要访问传递给指令的值,您可以使用 attrs 对象。

所以从指令中完全删除scope,然后获取值,在link函数中你可以这样做:

var myPara = scope[attrs['automaticangularmodelbinding']];

这将包含来自父范围的 extraParameterInFront。

如果该参数只是一个字符串,那就更简单了:

var myPara = attrs['automaticangularmodelbinding'];

【讨论】:

    猜你喜欢
    相关资源
    最近更新 更多
    热门标签