非HTML5占位符指令适用于ng-model?

时间:2013-08-22 17:02:11

标签: angularjs angularjs-directive

我遇到了一个问题,我的角色知识有点过于局限。我想要一个非html5占位符属性。以下是我之前在堆栈溢出时发现的一些代码:#/ p>

// Placeholder for non HTML5 browsers
app.directive("ngPlaceholder", function($log, $timeout) {
    var txt;
    return {
        restrict: "A",
        scope: { txt: "@ngPlaceholder" },
        link: function(scope, elem, attrs) {

            elem.on("focus", function() {
                if(elem.val() === scope.txt) {
                    elem.val("");
                }
                scope.$apply()
            })

            elem.on("blur", function() {
                if(elem.val() === "") {
                    elem.val(scope.txt);
                }
                scope.$apply()
            })

            // Initialise placeholder
            $timeout(function() {
                elem.val(scope.txt)
                scope.$apply();
            })
        }
    }
})

但是......将它与ng-model结合使用:

input(
  type="text"
  ng-model="card.number"
  ng-placeholder="0000-0000-0000-0000")

它消除了双向数据绑定!

继承人: http://plnkr.co/edit/1AvVOxb5O6P5pU3wIuKv?p=preview

我错过了什么?

更新很多人都在为这个相当烦人的问题提出解决方案here

4 个答案:

答案 0 :(得分:2)

使用$ parent引用父作用域中的模型,因为指令ngPlaceholder创建了一个隔离的作用域。 (这不是IE 9特有的。)

<input type="text" ng-placeholder="0000-0000-0000-0000" ng-model="$parent.card.number2"/>

答案 1 :(得分:2)

这个问题解决了在$ timeout延迟时,$ scope可能会在此期间发生变化的问题。它也使它成为跨浏览器。

// Placeholder for all browsers
app.directive("ngPlaceholder", function($log, $timeout) {
    return {
        restrict: "A",
        link: function(scope, elem, attrs) {
            var txt = attrs.ngPlaceholder,
                model = attrs.ngModel,
                placeholderSupport = 'placeholder' in document.createElement("input");

            //Use HTML5 placeholder attribute.
            if (placeholderSupport) {
                attrs.$set("placeholder", txt);
                return;
            }

            elem.on("focus", function(event) {
                if (elem.val() === txt) {
                    elem.val("");
                }
            });

            elem.on("blur", function(event) {
                if (elem.val() === "") {
                    elem.val(txt);
                }
            });

            scope.$watch(model, function (newValue, oldValue, scope) {
                if (newValue === undefined || newValue === "") {
                    elem.val(txt);
                    //scope.$apply(); not needed, since scope fired this event.
                }
            }, true);
        }
    }

});

答案 2 :(得分:1)

您看到了ngModel问题,因此应删除ngPlaceholder上的隔离范围。我意识到sza的解决方法有效,但我要强调的关键是ngPlaceholder不需要自己的范围。

例如,我在这里通过存储创建txt变量作为自己的局部变量来调整指令并删除对范围的引用。 http://plnkr.co/edit/43z1TZHFwmgLJ9wyystD?p=preview

// Placeholder for non HTML5 browsers
app.directive("ngPlaceholder", function($log, $timeout) {
    var txt;
    return {
        restrict: "A",
        link: function(scope, elem, attrs) {
            var txt = attrs.ngPlaceholder;

            elem.bind("focus", function() {
                if(elem.val() === txt) {
                    elem.val("");
                }
                scope.$apply()
            })

            elem.bind("blur", function() {
                if(elem.val() === "") {
                    elem.val(txt);
                }
                scope.$apply()
            })

            // Initialise placeholder
            $timeout(function() {
                elem.val(txt)
                scope.$apply();
            })
        }
    }
})

答案 3 :(得分:0)

IE中的占位符支持,颜色正常

app.directive('placeholder',['$timeout','$window', function($timeout,$window){
    var i = document.createElement('input');
    if ('placeholder' in i) {
        return {}
    }
    return {
        link: function(scope, elm, attrs){
            var userAgent = $window.navigator.userAgent;
            if(userAgent.indexOf("MSIE 9.0") <0){
                  return;
            } 
            if (attrs.type === 'password') {
                return;
            }
            $timeout(function(){
                elm.val(attrs.placeholder).css({"color":'#ccc'});
                elm.bind('focus', function(){
                    if (elm.val() == attrs.placeholder) {
                        elm.val('').css({"color":'#555'});
                    }
                }).bind('blur', function(){
                    if (elm.val() == '') {                      
                        elm.val(attrs.placeholder).css({"color":'#ccc'});
                    }
                });
            });
        }
    }
}]);

现场代码:http://plnkr.co/edit/ev6kQ3Ks31FhqAfCMDkc