ng-model to async xhr get / set字段在我的服务器上

时间:2015-10-01 00:47:10

标签: javascript html angularjs asynchronous

我使用Angular创建首选项页面。

基本上我在服务器上的mysql表中有这个字段,我想将我的文本框建模为异步xhr请求来设置它,然后得到它。

这是一个jsfiddle我试图拼凑起来,没有异步,虽然我无法将它拉下来:

<div ng-controller="MyCtrl">
        {{prefs.delay}}
        Type a number: <input type="text" ng-model="prefs.delay"/>
</div>

脚本:

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

function MyCtrl($scope, $q, $timeout) {

    var getPref = function(prefName) {
        /*
        var deferredMain_getPref = $q.defer();

        sendAsyncMessage(['getPref', prefName], function(aPrefVal) {
                deferredMain_getPref.resolve(aPrefVal);
        });
        */
        return prefStore[prefName]
    };


    $scope.prefs = {
        delay: getPref('delay')
    };

    $scope.$watch('prefs.delay', function(newValue) {
        sendAsyncMessage(['setPref', 'delay', newValue]);
    });


}

// check global pref store value with:
// content.document.getElementsByTagName('iframe')[0].contentWindow.wrappedJSObject.prefStore
// faking stuff below for demo
var prefStore = {
    delay: 100
};
function sendAsyncMessage(arrOfFuncNameAndArgs, aCallback) {
    if (arrOfFuncNameAndArgs[0] == 'setPref') {
        prefStore[arrOfFuncNameAndArgs[1]] = arrOfFuncNameAndArgs[2];
    } else if (arrOfFuncNameAndArgs[0] == 'getPref') {
        setTimeout(function() {
            aCallback(prefStore.delay);
        }, 1000);
    }
}

JSFiddle Link - 演示

在这个小提琴中,我试图伪造setTimeout的异步行为的延迟时间但是失败,因此删除了异步行为以向您显示Angular的工作原理。如何在超时时引入假异步?

1 个答案:

答案 0 :(得分:1)

这是在黑暗中拍摄的,我相信你在之后。首先,ng-pattern不会阻止输入,只会触发验证。相反,首先使用input[number]。我也猜测您希望看到您在<input />中设置的手动值,而不是键入的条目。为此,点击$event.preventDefault(),绑定到ng-keydown。这是一个包含在名为async的装饰器指令中的完整工作示例。请注意以下内容......

<input type="number" async ng-keydown="sync($event)" ng-model="model" />
.directive('async', ['myService', function(myService) {
    return {
        require: 'ngModel',
        link: function(scope, elem, attrs, ngModel) {

            scope.sync = function($event) {
                $event.preventDefault();

                myService.getValue().then(function(response) {
                    myService.setValue(response).then(function(final) { 
                        ngModel.$setViewValue(final)
                        ngModel.$render();
                    });
                });
            }
        }
    }
}]);

myService是一个模拟服务,利用$q$timeout来模拟异步行为......

.factory('myService', ['$q', '$timeout', function($q, $timeout) {

    function getValue () {
        var deferred = $q.defer();

        $timeout(function () {
            deferred.resolve(123);
        }, 250);

        return deferred.promise;
    }

    function setValue(value) {
        var deferred = $q.defer();

        $timeout(function () {
            deferred.resolve(value);
        }, 250);

        return deferred.promise;
    }

    return {
        getValue: getValue,
        setValue: setValue
    }
}]);

123 - 样本值 - 通过getValuesetValue函数以异步方式菊花链式连接。 getValue的结果也作为参数传递给setValue,以防在最终调用ngModel.$setViewValuengModel.$render()之前需要进一步操作。此外,您的目标是在getValue()中利用请求。到达那一点时,只需注入$http等服务并相应地建模......

function getValue () {
    return $http.get('/endpoint');
}

JSFiddle Link - 工作演示 - 输入1 =&gt; 500ms =&gt; 123

如果您希望最初阻止键控值,我的假设是错误的,您也可以绑定到ng-change并删除$event.preventDefault。如果您选择了此选项,则会看到您的初始输入值,然后按预期更改(获取/设置)。