Angular输入指令组(二)

Angular输入指令组(二)

果然,程序花很少的时间能写出来,然后要花大量的时间去改bug。像我这种学什么都一知半解的程序员更是如此。在这里,我想说,上一篇博客中的输入指令组(一)中的代码是不完美的。

问题背景

问题出在哪呢?上午在本地环境测试的时候还是没问题的。但是,我们的程序是要和后台打交道的,此时,问题出现了。我们访问数据的方式都是异步的,也就是说,指令开始加载的时候数据还没有来,数据来了,指令已经加载好了。上午我在本地测试的时候,数据都是直接赋值,模拟过去的,所以没有什么问题。怪就怪在,同步世界的我根本没有考虑异步世界该如何处理。

问题描述

由于指令加载的时候此时ngModel中的数据还是空,所以显示的时候并不能获取到值。所以,显示出来都是清一色的未填写。

分析

那该如何处理呢,最理想的办法是把指令的加载放在ajax的回调函数中,哦?视图写在控制器的中。算了,不可能。
实在不行就得用$watch了,这似乎是万能的。

解决问题

$watch接受两个函数作为参数,一个是当做被监控函数,一个是动作函数。考虑监控函数返回什么,之前一直想在ngModel上做文章,奈何ngModel打印出来是一个构造函数,然后不知道为什么new还报错,所以慢慢对ngModel失去兴趣了。但是,我监控的内容肯定还是input所在的作用域所绑定的变量。
ngModel是一个指令,他的作用是让一个作用域对象和input元素进行双向绑定,ngModel的值就是模型。我们要监控的就是这个模型。
于是代码就是这样。

app.filter('show',function(){
    return function(input){
        if(input){
            return input;
        }else{
            return "未填写";
        }
    }
});
app.directive('inputGroup',function($compile){
    return {
        restrict : 'A',
        require : 'ngModel',
        link : function(scope,element,attrs,ngModel){
            var subScope = scope.$new(true);
            subScope.label = attrs.label;
            subScope.value = ngModel;
            function toggleHiden(params){
                for(var i in params)
                    params[i] 
                && params[i].toggleClass 
                && params[i].toggleClass("hidden");
            }
            subScope.edit = function(){
                subScope.last = ngModel.$viewValue;
                subScope.value = subScope.last;
                toggleHiden(elements);
            }
            subScope.save = function(){
                toggleHiden(elements);
            }
            subScope.cancel = function(){
                subScope.value = subScope.last;
                ngModel.$setViewValue(subScope.last);
                element.val(subScope.last);
                toggleHiden(elements);
            }
            var div = $compile('<div><div>')(subScope);
            var label = $compile('<label>{{label}}</label>')(subScope);
            var span = $compile('<span ng-click="edit()">{{value|show}}</span>')(subScope);
            var save = $compile('<button ng-click="save()">保存</button>')(subScope);
            var cancer = $compile('<button ng-click="cancel()">取消</button>')(subScope);
            var elements = [element,save,span,cancer];
            var hiddens = [element,save,cancer];
            toggleHiden(hiddens);
            div.attr('class',attrs.classname);
            element.wrap(div);
            element.after(label);
            label.after(element);
            element.after(span);
            span.after(save);
            save.after(cancer);
            scope.$watch(function(){
                return scope.$eval(attrs.ngModel);
            },function(){
                subScope.value = scope.$eval(attrs.ngModel);
            });
        }
    }
});

这是控制器代码

    <script>
        var app = angular.module('app',[]);
        app.controller('testCtrl',function($http){
            var vm = this;
            var param = {time: "2016-10-17T13:29:52.344Z"};
            //基本的
            $http.post('/apis/anti/time',param).success(function(data){
                vm.time = data;
            });
            vm.a = 1;
            vm.b = 2;
        });
    </script>

视图是这样

    <input type="text" ng-model="vm.time" input-group label="用户名" classname="anti">
    <input type="text" ng-model="vm.b" input-group label="用户名" classname="anti">
    {{vm|json}}

注意:在控制器中我请求了后台的数据,如果是为了写demo完全可以用本地的json代替。相比上一个版本,又考虑了很多新的东西。对$watch和link函数的理解又深了一些。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值