Angular ng-model不绑定到输入字段

时间:2015-03-10 05:54:30

标签: javascript angularjs viewmodel angular-ngmodel asp.net-mvc-5.2

我有以下控制器工作,我可以使用ng-repeat来显示我拥有的ONE json对象。我只是使用ng-repeat来确保数据真正发生。但我无法弄清楚如何绑定我的输入字段以显示此编辑视图/模板中文本字段内的数据。

控制器

angular
    .module("renderIndex", ["ngRoute","ngCookies"])
    .config(config)
    .controller("favoritesController", favoritesController)
    .controller("newFavoriteController", newFavoriteController)
    .controller("editFavoriteController", editFavoriteController);

function config($routeProvider) {
    $routeProvider

        //...left out for brevity

        .when("/editfavorite/:searchId", {
            templateUrl: "/ng-js/ng-templates/editFavoriteView.html",
            controller: "editFavoriteController",
            controllerAs: "vm"
        })
        .otherwise({ redirectTo: "/" });
};

//...left out for brevity

function editFavoriteController($http, $window, $routeParams) {
    var vm = this;
    vm.search = [];

    var url = "/api/favorites/" + $routeParams.searchId;
    $http.get(url)
        .success(function (result) {
            vm.search = result;
        })
        .error(function () {
            alert('error/failed');
        })
        .then(function () {
            //Nothing
        });
};

控制器工作,它接受一个id参数,并在api端点URL的末尾使用并添加。我得到了一个很好的响应,这是一个json对象,我可以使用vm.search将其传递给视图,如果你注意到视图的底部我有一个ng-repeat(这只是那是因为我想确保一些数据实际上是通过网络而来的。当然它只重复一条记录,因为这是一个编辑页面,但它有效,但我的绑定输入没有在文本字段中显示任何内容当视图呈现时。这必须是简单的,任何人都可以帮忙吗?

EditView / Angular Template

<div class="small-12 column"><h3>Edit Search</h3></div>
<div class="small-12 column">
    <form name="editFavoriteForm" novalidate ng-submit="vm.update()">
        <input name="userId" type="hidden" ng-model="search.userId" />
        <label for="name">Name</label>
        <input name="name" type="text" ng-model="vm.search.name" />
        <label for="description">Description</label>
        <textarea name="description" rows="5" cols="30" 
                  ng-model="vm.search.description"></textarea>
        <input type="submit" class="tiny button radius" value="Save" /> | 
        <a href="#/" class="tiny button radius">Cancel</a>
    </form>
</div>
<div data-ng-repeat="s in vm.search">
    <p>{{s.name}} - {{s.userId}}</p>
</div>

所以只是重申....数据是在vm.search中发送的,它是我期待的一个数据库记录,我知道这是因为它在我使用ng-repeat时显示。但是当我使用ng-model='vm.search.name'时,我没有将数据绑定到该字段,以便我可以编辑它。谁能指出我做错了什么?

如下所示,我将一些测试数据放入并转到该项目的编辑页面,name = asdf&amp;用户id = fec87a96-22d7-4e8c-8991-fa01df60c5c0。这两个都是预期值,但使用相同的vm.search模型在有界文本字段中没有显示任何内容。

enter image description here

2 个答案:

答案 0 :(得分:0)

这里答案非常简单,感谢菲尔。首先,我不应该在代码底部使用ng-repeat作为一种测试方法,看看我的值是否存在,使用类似的东西要好得多:

 <pre>{{ vm.search | json }}</pre>

这会(在代码视图中)吐出vm.search中保存的实际json对象,并且变量名后面附加| json只会帮助格式化页面上的json。如果你没有使用它,你只会在一行上看到所有内容。再次@Phil,谢谢你的提示!

我没有意识到的一件事是我result来自http.get来自vm.search变量的vm.search号召唤。实际上是一个数组。很明显,你说,但是我没有想到只从该数组中获取第一项并将其填入我名为$http.get("/api/favorites") .success(function (result) { vm.searches = result; }) 的变量中,而不是我这样做:

$http.get("/api/favorites")
.success(function (result) {
    vm.searches = result[0];
})

事实上我应该这样做:

 <pre>{{ vm.search | json }}</pre>

现在看看差异,让我们保存出来的结果

[
  {
    "searchId": 91,
    "userId": "fec87a96-22d7-4e8c-8991-fa01df60c5c0",
    "name": "xxx123",
    "description": "123xxx",
    "created": "2015-03-11T01:12:37.32",
    "searchString": "/?"
  }
]

使用每种方法,首先不使用第一个数组元素,我们得到:

result[0]

现在,如果我们使用后一种方法提取结果,直接进入第一个元素{ "searchId": 91, "userId": "fec87a96-22d7-4e8c-8991-fa01df60c5c0", "name": "xxx123", "description": "123xxx", "created": "2015-03-11T01:12:37.32", "searchString": "/?" } ,我们将结果作为对象,而不是仅包含在一个项目的数组中的对象。

{{1}}

我知道解释所有这一切似乎很乏味,但对于像我这样忽视它的人来说,这是你的模型绑定或不绑定到每个文本字段的输入值之间的区别,即使它是非常简单,像我这样的其他新手很可能会忽视这一点。我相信有人可以更好地解释两者之间的区别。

感觉任何人都可以编辑我的答案并更好地解释,特别是如果它需要更少的代码行就可以了!

答案 1 :(得分:-4)

控制器和视图相互通信的方式是通过$ scope。在您的情况下,控制器的vm变量是控制器的本地变量,在您将其声明为var vm时无法查看。

当您在视图中访问vm时,它实际上会创建一个新变量vm并将其放在范围内。

要纠正它,您需要将$ scope作为控制器依赖项传递,并在控制器中使用$ scope.vm。您的控制器应如下所示:

function editFavoriteController($scope, $http, $window, $routeParams) {
    $scope.vm.search = [];

    var url = "/api/favorites/" + $routeParams.searchId;
    $http.get(url)
        .success(function (result) {
            $scope.vm.search = result;
        })
        .error(function () {
            alert('error/failed');
        })
        .then(function () {
            //Nothing
        });
};

使用这些视图和控制器现在应该引用相同的&#39; vm&#39; $ scope中可用的变量。

请注意,您无需在视图中明确使用$ scope.vm作为&#39; vm&#39;在视图中隐式引用$ scope.vm。