2013-03-21 58 views
8

我正在爲觸摸屏計算機構建一個Web應用程序,該應用程序需要屏幕上的鍵盤,並試圖使用此優秀(或至少唯一一個我能夠發現這不是可怕的)鍵盤。 https://github.com/Mottie/Keyboard/從帶有「on change」回調的jQuery插件更新AngularJS模型

問題是,正如您可能已經猜到的那樣,使用屏幕鍵盤時模型不會更新。這是我的代碼,這樣的作品,但它的種種醜惡:

的partitial HTML:

<input type="text" class="keyboard" ng-model="newUser.name"> 
<input type="text" class="keyboard" ng-model="newUser.email> 

初始化鍵盤,從partitial頁面控制器:

$('.keyboard') 
.keyboard({ 
    stickyShift: false, 
    usePreview: false, 
    autoAccept: true, 

    change: function(e, kb, el) { 
     $scope.newUser.name = el.value; 
    } 
}); 

所以上由jQuery插件觸發的更改我可以運行一些東西。顯然,這隻能更新單個字段/模型,名稱爲1(而電子郵件根本不工作並將覆蓋名稱字段),我需要任何數量的字段在與鍵盤一起使用時進行更新,而正確的一個。我如何在一個不太可怕的,沒有硬編碼(如果可能的話,而不是太複雜)的方式下解決這個問題?

+0

使用指令調用優秀的鍵盤的鍵盤方法。在這種情況下,你可以擁有元素的ngModel。 – Abilash 2013-03-21 12:18:19

+0

建議類似於ui-select2的angular-ui.js – Abilash 2013-03-21 12:19:25

+0

Angular-UI對此有必要或甚至有幫助嗎?除了簡單的文本字段之外,對於這個特殊的問題,除非它還包含了更好的屏幕上的鍵盤,否則就是過度的。 – 2013-03-21 12:25:43

回答

12

在Angular中寫這個的方法是實際編寫一個指令。你可以用一個特定的類名來指定一個指令。

所以,你的指令將看起來像

app.directive('keyboard',function(){ 
    return { 
    require : '?ngModel', 
    restrict : 'C', 
    link : function(scope,element,attrs,ngModelCtrl){ 
     if(!ngModelCtrl){ 
     return; 
     } 
     $(element).keyboard({ 
     stickyShift: false, 
     usePreview: false, 
     autoAccept: true, 

     change: function(e, kb, el) { 
      ngModelCtrl.$setViewValue(el.value); 
     } 
    }); 
    } 
    }; 
}); 

現在,如果任何元素具有一個類定義,然後鍵盤和NG-模型,你的鍵盤應該彈出。希望這可以幫助。

+0

它確實如此,這很好。我是AngularJS的新手,沒有web編程背景,但我可以告訴你這是一個很好的框架。我將不得不嘗試弄清楚何時使用指令。 – 2013-03-21 12:55:14

+0

哇..我寫了那個盲..所以,力求它沒有任何修改工作。 如果您需要操作DOM或查詢DOM並獲取元素,則通常需要指令。 – ganaraj 2013-03-21 13:03:40

+0

我希望你不需要將'element'作爲'$(element)'包裝,因爲它已經是一個'jQuery'對象。 – 2013-06-24 14:29:32

2

我修改了ganraj指令。現在,模型每次點擊鍵盤按鈕時都會更新。

app.directive('keyboard',function(){ 
    return { 
    require : '?ngModel', 
    restrict : 'C', 
    link : function(scope,element,attrs,ngModelCtrl){ 
     if(!ngModelCtrl){ 
     return; 
     } 

     $(element).keyboard({ 
     stickyShift: false, 
     usePreview: false, 
     autoAccept: true, 

     change: function(e, kb, el) { 
      if(!scope.$$phase && !scope.$root.$$phase) 
      { 
       scope.$apply(function(){ 
        ngModelCtrl.$setViewValue(el.value); 
       }); 
      } 
     } 
    }); 
    } 
    }; 
});