使用AngularJS在服务调用后呈现所有表单值

时间:2014-11-26 21:04:02

标签: javascript angularjs forms

我有一个Angular文章表单,我正在使用服务调用填充。问题是,为了使验证和数据绑定起作用,我必须在每个表单输入上使用$setViewValue$render。我想做的只是设置表单的数据模型,然后以某种方式呈现整个表单。

以下是我的工作样本:

var _promise = articleService.getArticle($scope.params.articleId);
_promise.then(
    function(data) {
        $scope.articleForm.title.$setViewValue(data.item.title);
        $scope.articleForm.title.$render();
        $scope.articleForm.bodytext.$setViewValue(data.item.body);
        $scope.articleForm.bodytext.$render();
        $scope.articleForm.keywords.$setViewValue(data.item.keywords);
        $scope.articleForm.keywords.$render();
    },
    function() {
        $scope.setMessage('There was a network error. Try again later.', 'error');
    }
);

下面的代码直观地完成了相同的结果(只是不渲染绑定,比如在验证中将字段更新为脏):

var _promise = articleService.getArticle($scope.params.articleId);
_promise.then(
    function(data) {
        // $scope.article breakdown: article.title, article.body, article.keywords
        $scope.article = angular.copy(data.item);
        // some sort of complete form render???
    },
    function() {
        $scope.setMessage('There was a network error. Try again later.', 'error');
    }
);

HTML:

<form name="articleForm" novalidate role="form">
    <!-- TITLE -->
    <div class="form-group" ng-class="{ 'has-error' : (articleForm.title.$invalid && !articleForm.title.$pristine) || (submitted && articleForm.title.$pristine) }">
        <label>Title</label>
        <input type="text" name="title" ng-model="article.title" ng-minlength="3" required>
        <p ng-show="(articleForm.title.$error.required && !articleForm.title.$pristine) || (submitted && articleForm.title.$pristine)" class="help-block">A title is required.</p>
        <p ng-show="articleForm.title.$error.minlength" class="help-block">Title is too short.</p>
    </div>
    <!-- BODY -->
    <div class="form-group" ng-class="{ 'has-error' : articleForm.bodytext.$invalid && !articleForm.bodytext.$pristine }">
        <label>Article Body</label>
        <div text-angular ng-model="article.body" ng-change="updateBody()" id="bodytext" name="bodytext"></div>
    </div>
    <!-- KEYWORDS -->
    <div class="form-group" ng-class="{ 'has-error' : (articleForm.keywords.$invalid && !articleForm.keywords.$pristine) || (submitted && articleForm.keywords.$pristine) }">
        <label>Keywords</label>
        <input type="text" name="keywords" ng-model="article.keywords" ng-minlength="3" ng-maxlength="150" required>
        <p ng-show="(articleForm.keywords.$error.required && !articleForm.keywords.$pristine) || (submitted && articleForm.keywords.$pristine)" class="help-block">At least one keyword is required.</p>
        <p ng-show="articleForm.keywords.$error.minlength" class="help-block">Keywords is too short.</p>
        <p ng-show="articleForm.keywords.$error.maxlength" class="help-block">Keywords is too long.</p>
    </div>
</form>

我觉得应该有一个简单的解决方案,因为这是一个常见的情况,但我搜索得很高,没有明确的答案。也许我只是以错误的方式接近这个?

1 个答案:

答案 0 :(得分:0)

好吧,我找到了一个有效的解决方案,但我不认为这比单独设置所有表单字段更好。我会在这里发布,以防它以某种方式帮助其他人。

// set all the values via the angular model
$scope.article = angular.copy(data.item);

// without a timeout all the fields will still be unset (being asynchronous)
$timeout(function() {
    // loop through all the form values
    angular.forEach($scope.articleForm, function(value, key){
        if(typeof value === 'object' && key !== '$error'){
            // reset the view value and render, to process the updates on the form
            $scope.articleForm[key].$setViewValue($scope.articleForm[key].$viewValue);
            $scope.articleForm[key].$render();
        }
    });
});