【问题标题】:Angular directive ng-model working for arrays but not stringAngular 指令 ng-model 适用于数组但不适用于字符串
【发布时间】:2017-11-13 21:07:05
【问题描述】:

ng-model 指令似乎缺少对 JavaScript 中实际对象的引用,但仅限于字符串值。使用字典对象列表并使用ng-repeat 循环遍历元素,如下所示,它可以工作。

我只能认为这可能是由于返回数组的行为就像返回对对象的引用,而返回字符串变量只是返回文字字符串,抵消了 Angular 的双向数据绑定能力和给我留下一个变量,它的值仍然是undefined

为什么下面的服务模块无法从视图中提取变量 gitRelease 的更新值?

在服务模块中我有这个功能:

(function () { //start iife

    'use strict';

    angular.module('gms.autoDeploy')
        .factory('AutoDeployService', ["$http", "$q", "$log", "$cookies", "APP_CONFIGS", "SweetAlert", "$timeout", "GridSettingsService", "APP_USER", AutoDeployService]);

    function AutoDeployService($http, $q, $log, $cookies, APP_CONFIGS, $timeout, SweetAlert, GridSettingsService, APP_USER) {

        var tibcoCopyJobs = [];
        var gitRelease = "";

        function addNewTibcoCopyJob() {
            tibcoCopyJobs.push({
                sourceServer: "",
                sourcePath: "",
                destinationServer: "",
                destinationPath: ""
            });
        }

        function getTibcoCopyJobs() { return tibcoCopyJobs; }
        function getGitRelease(){ return gitRelease; }

        function extractFormData() {
            console.log(gitRelease);
            for (var i = 0; i < tibcoCopyJobs.length; i++) {
                console.log(tibcoCopyJobs[i]);
            }
        }

        return {
            addNewTibcoCopyJob:             addNewTibcoCopyJob,
            getTibcoCopyJobs:               getTibcoCopyJobs,
            getGitRelease:                  getGitRelease,
            extractFormData:                extractFormData
        };
    } //end AutoDeployService
}()); //end iife

在这个控制器上使用它:

angular.module("gms.autoDeploy").controller('AutoDeployController', ['$scope', '$compile', 'AutoDeployService',
function ($scope, $compile, AutoDeployService) {

        var model = this;

        init();

        function init() {
            model.tibcoCopyJobs = AutoDeployService.getTibcoCopyJobs();
            model.gitRelease = AutoDeployService.getGitRelease();
        }

        function btn_addNewTibcoCopy() { AutoDeployService.addNewTibcoCopyJob(); }

        function btn_extractFormData() { AutoDeployService.extractFormData(); }

        model.btn_addNewTibcoCopy = btn_addNewTibcoCopy;
        model.btn_extractFormData = btn_extractFormData;
    }
]);

为这个视图提供功能:

<div ng-controller="AutoDeployController as autoDeploy">
<div class="container-fluid">

<div class="row">
    <div class="col-md-2">
        <input type="text" class="form-control" ng-model="autoDeploy.gitRelease" placeholder="MM-DD-YYYY">
    </div>
</div>

<div class="row">
    <fieldset class="col-md-2" style="margin-bottom: 10px" ng-repeat="item in autoDeploy.tibcoCopyJobs track by $index">
        <legend>Copy</legend>

        <input type="text" class="form-control" placeholder="Source Server..." ng-model="item.sourceServer">
        <br/>
        <input type="text" class="form-control" placeholder="Source Path..." ng-model="item.sourcePath">
        <br/>
        <input type="text" class="form-control" placeholder="Destination Server..." ng-model="item.destinationServer">
        <br/>
        <input type="text" class="form-control" placeholder="Destination Path..." ng-model="item.destinationPath">
    </fieldset>
</div>

<button ng-click="autoDeploy.btn_extractFormData()">extract</button>
<button ng-click="autoDeploy.btn_addNewTibcoCopy()">TIBCO copy</button>
</div>
</div>

【问题讨论】:

  • 试着把你的字符串变成一个只有一个参数的对象。例如var data = {gitRelease: ''} 。要使双向绑定正常工作,您必须使用对对象或数组的引用,而不是文字。此外,您必须清空并重新填充数组才能更改它,或者如果您想重新分配,您需要浅观察参考。

标签: javascript angularjs model-view-controller


【解决方案1】:

我想你已经在你的问题中解释了原因。数组通过引用返回,而字符串只是按值复制。但我会尽量让它更清楚一点。

当你这样做时

model.gitRelease = AutoDeployService.getGitRelease();

模型对象将像这样创建属性 getRelease:

{getRelease: "", ... (more properties from the ctrl)}

所以无论你在视图中更新什么,它只会更新控制器中的 getRelease。

一种可能的解决方法就像 Jags 在评论中提到的那样。

或者您可以在 ctrl 中引用您的服务

var model = this;
model.autoDeployService = AutoDeployService;

在你看来

<input type="text" class="form-control" ng-model="autoDeploy.autoDeployService.gitRelease" placeholder="MM-DD-YYYY">

应该可以的。

【讨论】:

  • 感谢您的澄清,您是使用检查工具查看模型对象的详细信息,还是有描述模型对象布局的文档?至于解决方案,我不确定效率或是否符合关注点分离 w.r.t. MVC 方法通过直接从视图中引用服务,所以我在服务中创建了一个新字典来保存简单的字符串变量,我只是像对待 tibcoCopyJobs 对象一样对待它。本质上使用var singleEntryData = { gitRelease: "" };... ng-model="autoDeploy.singleEntryData.gitRelease" ...
  • 我通常使用浏览器中的检查工具,您可以在源代码中设置断点并检查对象。我认为直接引用该服务没有问题。这取决于个案或偏好。想象一下,如果您有一个包含大量数据的大型模型,并且必须在多个控制器之间共享数据,那么使用服务直接引用将是一种很好的方法。
  • 是的,这很有意义。考虑到您的实现对于大型项目来说是一种更好的做法,我将把这个给您。
猜你喜欢
  • 2015-05-05
  • 1970-01-01
  • 2021-11-27
  • 1970-01-01
  • 2014-07-13
  • 1970-01-01
  • 1970-01-01
  • 2017-08-02
  • 2019-11-17
相关资源
最近更新 更多