javascript - 使用 AngularJS 提交表单的正确方法是什么?

标签 javascript angularjs forms

所以我正在编写一个表单,并且目前正在编写提交函数。此提交函数应检查表单是否有效,将其 POST 到服务器,然后在收到响应时使用 ui-router 更改状态。

所有相当简单的东西,尽管它让我思考。在 AngularJS 的大多数示例中,我看到以下内容:

$scope.submit = function() {
    var params = { someKey: $scope.someKey };
    $http.post(...);
};

对我来说,这似乎是倒退的.. 这对 $scope.submit 是否严重影响了 $scope 的当前状态,因此很难(呃)测试?

我最近写了一些类似的东西:

$scope.submit = function(params) {
    // Any sanity checking, such as checking various parameters exist
    if(angular.isUndefined(params.summonerName)) {
        throwToysOutOfPram();
        return;
    }
    $http.post(...);
};

然后在 View 中,我有这样的东西:

<button ng-click='submit({ summonerName: summonerName, twitchName: twitchName })'>Submit</button>

对我来说,从可测试性的 Angular 来看,这似乎是最有意义的,但我内心深处对于将这种“逻辑”放入 View 中感觉很糟糕。普遍共识是什么?

<小时/>

AddStreamerCtrl

angular.module('project.streamers')
.controller('AddStreamerCtrl', ['$scope', 'channelName', 'Streamer', 'regions', 'languages', function ($scope, channelName, Streamer, regions, languages) {
    $scope.channelName = channelName;
    $scope.regions = regions;
    $scope.languages = languages;

    $scope.submit = function(params) {
        Streamer.save(params, function() {
            console.log('it worked!');
        }, function() { 
            console.error('something went wrong :(');
        });
    };
}]);

streamers.add 状态设置

angular.module('project.streamers')
.config(['$stateProvider', function ($stateProvider) {
    $stateProvider.state('streamers.add', {
        templateUrl: '/streamers/create.html',
        url: '/add',
        params: {
            channelName: null,
        },
        controller: 'AddStreamerCtrl',
        resolve: {
            channelName: function($stateParams) {
                return $stateParams.channelName;
            },
            languages: function(Language) {
                return Language.get();
            },
            regions: function(Region) {
                return Region.get();
            }
        }
    }); 
}]);

创建.html

<h1>Streamer Sign Up</h1>
<p>This form will guide you through the steps of adding your stream to our list. In order to qualify, you must have a valid League of Legends and Twitch account.</p>

<p class='panel callout'>Please note that the administrators of this website reserve the right to remove your stream at their discretion.</p>

<form name='addStreamerForm' ng-submit='submit(data)'>
    <label>Twitch Channel 
        <input type="text" ng-model='data.channelName' name="channelName" placeholder="Channel Name" required>
    </label>
    <p>This is your Twitch username. For example, if your url is <code>twitch.tv/aredherring</code>, then your username would be <code>aredherring</code>.</p>

    <label>Language
        <select ng-options='language.id as language.name for language in languages' ng-model='data.language' required>
            <option value=''>Select a language</option>
        </select>
    </label>
    <p>This is the language you stream in. If you are multi-lingual, please select the language you will use most often.</p>

    <label>Region 
        <select ng-options='region.id as region.name for region in regions' ng-model='data.region' required>
            <option value=''>Select a region</option>
        </select>
    </label>
    <p>This is the region your League of Legends account is on. If you have accounts on multiple regions, select the region you are most likely to play on on a day-to-day basis.</p>

    <label>Summoner Name
        <input type="text" name="summonerName" ng-model='data.summonerName' placeholder="Summoner Name" required>
    </label>
    <p>This is your summoner name for your League of Legends account. If you have multiple accounts, specify the account that you use most often.</p>

    <p>We will use the League of Legends API and Twitch API to retrieve data about your accounts.</p>


    <label>
        <input type="checkbox" name="tAndCs">
        I agree to the <a ui-sref='termsAndConditions'>Terms and Conditions</a>
    </label>

    <input type='submit' class='button' value='Submit'>
</form>

最佳答案

努力维持低位coupling和高cohesion在软件开发中,通常最好的做法是尽可能将功能与其操作的数据分开,这样它就可以用于一个数据集的多个实例。在这种情况下,是的,您上面概述的第二种方法更理想,因为它不依赖于附加到 $scope 的特定变量。

假设您有 ng-model="data.summonerName"ng-model="data.twitchName",您可以这样做:

<button ng-click='submit(data)'>Submit</button>

这样,如果您稍后发现(例如)需要能够从代码本身(或某些unit-testing代码)调用提交,您可以非常轻松地做到这一点:

$scope.submit({summonerName: testSummonerName, twitchName: testTwitchName});

使用原始方法,您必须对 $scope 属性进行一些时髦的操作。

此外,使用 Angular,表单验证几乎可以完全在标记中完成,并对用户输入提供即时响应(请参阅他们的 forms guide )。

Keep in mind that while client-side validation plays an important role in providing good user experience, it can easily be circumvented and thus can not be trusted. Server-side validation is still necessary for a secure application.

关于javascript - 使用 AngularJS 提交表单的正确方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27893611/

相关文章:

java - 验证 JavaScript 代码

angular - 如何在 Angular 的第一次更改时触发表单输入验证

javascript - 在文本框中键入/输入数据时显示输入的值

javascript - 在 jQuery UI MultiSelect Widget 中选择复选框

java - 如何动态导入javascript和css文件

javascript - 有 <br> 时,使用 jQuery 的文本幻灯片无法正常运行

angularjs - Angular : Bind callback function using & and pass-in arguments

javascript - 如何将 ng-if 与异步函数一起使用?

带有 ControllerAs 和 TypeScript 类的 AngularJs 指令

c# - 在 C# 窗体上捕获关闭事件