2013-09-26 67 views
0

我具有各種輸入(包括後面將要說明的指令)如:使用控制器的屬性/方法

<input mask-value="ssn" validate="checkSsn"/> 
<input mask-value="pin" validate="checkPin"/> 

這些屬性是在所述控制器:

app.controller("Ctrl", ['$scope', function ($scope) { 
    $scope.ssn = ""; 
    $scope.pin = ""; 

    $scope.checkSsn = function() { /* validate $scope.ssn */ }; 
    $scope.checkPin = function() { /* validate $scope.pin */ }; 
}]); 

最後, maskValue指導意見:

app.directive("maskValue", function() { 
    return function (scope, element, attrs) { 
     /* does some focus/blur magic and string replacement */ 
     scope[attrs.maskValue] = this.value; 
     scope[attrs.validate](); 
    }; 
}); 

這是有效的,但它似乎是對我的角度誤用。相反,它會更有意義使用一個孤立的範圍爲:

scope: {validate: "&"} 

然後,我可以用scope.validate()代替scope[attrs.validate]()但是,與隔離範圍我不能更新控制器中的相應值。使用{maskValue: "="}不起作用,因爲這會嘗試更新父級的maskValue屬性而不是特定值。我認爲使用{ssn: "="}可以工作,但是我必須更新控制器的特定屬性,而不是將其設置爲使指令不靈活的指令屬性。顯然使用$parent也不建議。

我該如何動態訪問控制器內部的隔離範圍指令?

編輯:我不能投入使用ng-model=ssn等。因爲在mask-value的焦點/模糊事件期間,輸入的實際值發生了變化。例如,它可能會變成*****####,但我需要在某處存儲實際值#########,並且控制器似乎是適當的地方,因爲控制器稍後會將其用於其他原因。

+0

在'='屬性中使用隔離範圍完全符合您的要求。你爲什麼說它不起作用?你能提供一個Plunker/jsFiddle腳本嗎? –

+0

@MichaelBenford我會設置一個。 '='不能正確運行,因爲它會更新控制器中的'maskValue'(不存在)。我可以做例如'ssn:「=」'但是我依靠一個特定的值。我想能夠透明地更新一個屬性 –

+0

@MichaelBenford你可以看到這是有效的:http://jsfiddle.net/MmyvX/ - 這是我嘗試以更有角度的方式(我認爲)使用隔離範圍。它不起作用:http://jsfiddle.net/MmyvX/1/ –

回答

2
<div ng-app=foo> 
    <div ng-controller=Ctrl> 
    {{ssn}} 
    <input mask-value="ssn" validate="checkSsn()"> 

app = angular.module("foo", []); 

app.controller("Ctrl", ['$scope', function ($scope) { 
    $scope.ssn = ""; 
    $scope.checkSsn = function() { console.log($scope.ssn); }; 
}]); 

app.directive("maskValue", function() { 
    return { 
     scope: { 
      validate: "&", 
      maskValue: "=" 
     }, 
     link: function (scope, element, attrs) { 
      element.bind("change", function() { 
       scope.maskValue = this.value; 
       scope.$apply(); 
       scope.validate(); 
      }); 
     }, 
    }; 
}); 

http://jsfiddle.net/bfDqy/

編輯:

他們說它是bett呃通過,要評估的,因爲在Anguular一些錯誤處理特點的參數$apply表達:

var value = this.value; 
scope.$apply(function() { 
    scope.maskValue = value; 
}); 
+0

這實際上有效!儘管如此,我有點困惑。我想'='接受屬性*值*而不是屬性名稱來更新到父項。它是完美的:) :)根據文檔 –

+0

,'='與父範圍的模型建立了兩個方向綁定。唯一的事情是在事件處理程序內部,你需要調用'$ apply',以便它知道更新綁定。 – akonsu

+0

我必須在'.validate()'後面調用'scope。$ apply()',因爲'.validate()'更新了控制器的作用域(特別是它設置了'$ scope.error'。是否只是預期的? –

0

我很抱歉,但爲什麼不只是這樣做:

app = angular.module("foo", []); 

app.controller("Ctrl", ['$scope', function ($scope) { 
    $scope.ssn = ""; 
    $scope.validate = function() { console.log($scope.ssn); }; 
}]); 

app.directive("maskValue", function() { 
    return { 
     link: function (scope, element, attrs) { 
      element.bind("change", function() { 
       scope.validate(); 
      }); 
     }, 
    }; 
}); 

和HTML這樣的:

<div ng-app=foo> 
    <div ng-controller=Ctrl> 
     <input ng-model="ssn" mask-value /> 
    </div> 
</div> 
1

我知道你已經得到的回答你的問題,但我認爲這是值得一提的由於您似乎正在進行一些驗證,您可以使用Angular的內置功能來執行此操作,但仍然可以使用ng-model。這裏有一個例子:

app.directive("maskValue", function ($parse) { 
    return { 
    restrict: 'A', 
    require: 'ngModel', 
    link: function (scope, element, attrs, ngModel) { 
     if (!ngModel) return; 
     var validator = $parse(attrs.validator)(scope); 

     ngModel.$render = function() { 
     var hasFocus = document.activeElement == element[0]; 
     if (ngModel.$valid || hasFocus) element.val(ngModel.$modelValue) 
     else element.val('#######'); 
     }; 

     element.bind('blur', function() { 
     ngModel.$setValidity('maskValue', validator(this.value)) 
     ngModel.$render(); 
     }); 

     element.bind('focus', function() { 
     ngModel.$render(); 
     }); 
    } 
    }; 
}); 

該指令,以便與ng-model一道,控制視圖如何更新使用NgModelController。在這個人爲的例子中,當元素失去焦點並且驗證函數返回false時,它會簡單渲染########。但是當控制再次聚焦時,它將呈現其真實價值,以便用戶可以改變它。請注意,綁定到控件的作用域的屬性在其視圖隨元素狀態(有效或無效)發生相應更改時保持不變。你可以看到一個工作示例here

相關問題