【问题标题】:ngModel not updating in selectngModel 未在选择中更新
【发布时间】:2015-04-14 11:20:45
【问题描述】:

我有一个基于服务器发送的配置的指令渲染输入。除了“选择”输入外,一切都很好。 无论我尝试什么,ng-model 都不会更新。 我已经对代码进行了很多修改以隔离问题:

Javascript:

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

    myApp.factory('DynamicData', [function() {
         return {
            data: {
              backup_frequency: 604800
            }
        };

    }])
    .directive('dynamicInput',
        ['$compile', 'DynamicData', function($compile, DynamicData) {

            /**
             * Render the input
            */
            var render = function render() {
                var input = angular.element('<select class="form-control" ng-model="inner.backup_frequency" ng-options="option.value as option.title for option in options"></select>');
                return input;
            };

            var getInput = function ()
            {
                var input = render();
                return input  ? input[0].outerHTML : '';
            };

            var getTemplate = function(){

                var template = '<div class="form-group">' +
                                'Select input ' +
                                '<div class="col-md-7">' + getInput() + '</div>' +
                            '</div>';
                return template;
            }; 

            return {
                restrict : 'E',
                scope: {
                    content:'=content',
                },

                link : function(scope, element, attrs) {
                    var template = getTemplate();

                    scope.options = [
                      {title: "Daily", value: 86400},
                      {title: "Weekly", value: 604800},
                      {title: "Monthly", value: 2678400},
                      ];
                    scope.inner = DynamicData.data;
                    console.info('inner data', scope.inner);

                    element.html(template);
                    element.replaceWith($compile(element.contents())(scope));


                }
            };
      }])
      .controller('FormCtrl', ['DynamicData', '$scope', function (DynamicData, $scope){
        $scope.app = {};

        $scope.save = function save() {
          $scope.value = DynamicData.data.backup_frequency;
          console.info('DynamicData', DynamicData.data);
        };
      }]);

HTML:

  <head>
    <script data-require="angular.js@1.3.8" data-semver="1.3.8" src="https://code.angularjs.org/1.3.8/angular.js"></script>
    <link href="style.css" rel="stylesheet" />
    <script src="script.js"></script>
  </head>

  <body>
    <h1>Dynamic Input :</h1>
    <div data-ng-controller="FormCtrl">
      <dynamic-input class="form-group" content="app"></dynamic-input>
      <span data-ng-bind="value"></span><br/>
      <button class="btn btn-primary" ng-click="save()">Save</button>
    </div>
  </body>

</html>

有一个可用的工作插件:http://plnkr.co/edit/mNBTJzZXjX6mLyPz6NCI?p=preview

你知道为什么选择中的 ng-model 没有更新吗?

编辑:我想要实现的是更新变量“inner.backup_frequency”(我的工厂 DynamicData 返回的对我的数据对象的引用)。正如您在 plunker 中看到的,每当我更改 select 中的选项时,ng-model 中包含的变量都不会更新。

感谢您的宝贵时间。

【问题讨论】:

  • 你想让&lt;span data-ng-bind="value"&gt;&lt;/span&gt;&lt;br/&gt;每次点击都不同..还是选择选项中的值有效..请解释
  • 嗨,您是否尝试过获取 select 上的 on change 事件并在 javascript 中设置 $scope.varaible 而不是 $scope.$apply() 只是为了查看它是否与元素在 $digest 循环之外?
  • 请参阅stackoverflow.com/a/22890796/446030,了解编译和放置在 dom 中的顺序。

标签: javascript angularjs


【解决方案1】:

我已经修好了。您需要做的不是用编译后的内容替换元素的内容,而是用原始 HTML 替换它,然后然后编译它。

element.html(template);
$compile(element.contents())(scope);

Working Plunker.

编辑:我已经编辑了您的代码以在没有指令的情况下工作:

Plunker without directive.

EDIT 2:也是一个使用指令但没有编译的版本:

Plunker.

【讨论】:

  • 您好,谢谢您的回答,它有效。但是,我真的很想减轻我的 DOM 并删除“动态输入”HTML 标记。有什么想法吗?
  • @AlexandreNucera 是的,看起来该指令所做的只是生成硬编码的 HTML,为什么不直接使用它并丢失编译等?
  • 好吧,这似乎可以解决问题: var e =$compile(template)(scope); element.replaceWith(e); (明天我会给你赏金,我要等21小时)
  • @AlexandreNucera 我也更新了我的答案,我加入了一个新的 plunker,可以在没有指令的情况下做同样的事情。如果有帮助的话.. :)
  • 我需要该指令,我只是不希望它出现在 DOM 中。感谢您的帮助!
【解决方案2】:

我遇到了类似的问题,发现如果您直接将 ng-model 绑定到如下范围变量,则范围变量选择将不会更新。

<select ng-model="selection" ng-options="option for option in options">

相反,在您的范围内定义一个视图模型并将 ng-model 绑定到一个视图模型字段,该视图模型字段将被更新。

<select ng-model="viewmodel.selection" ng-options="option for option in options">

在您的控制器中,您应该这样做:

app.controller('SomeCtrl', ['$scope'
    function($scope)
    {
        $scope.viewmodel = {};
    });

【讨论】:

  • 对我有很大帮助的要点: • 模型需要是范围变量上的 属性 - 而不是范围变量 • 最好是 not 在 JS 中分配范围变量的属性 - 只需在 HTML 中引用它,Angular 就会创建并更新它
  • 请记住:“范围不是模型,范围引用模型”和“只要你有 ng-model 就必须有一个点 在某处。如果你没有一个点,那你就做错了。” more
猜你喜欢
  • 2017-05-01
  • 2023-03-05
  • 2019-07-09
  • 1970-01-01
  • 2023-04-02
  • 2014-05-12
  • 2020-09-14
  • 2021-06-11
  • 1970-01-01
相关资源
最近更新 更多