2013-08-22 4 views
5

Mam następujący na stronie - pełny kod w tym Plunkerangularjs on wprowadzić dyrektywę w sprawie wejścia nie stanowią wartość oszczędności modelu

Istnieje zwyczaj dyrektywa onEnter że wywołuje funkcję po naciśnięciu ENTER na wejście formie czatu . Fragment kodu poniżej

//**HTML View** 
<div ng-controller="mainCtrl"> 
    <ul> 
     <li ng-repeat="chat in chatMessages"> 
     {{chat.username}}<br/> 
      {{chat.message}} 
     </li> 
    </ul> 
</div> 
<form id="chatForm" name="chatForm" ng-controller="formCtrl"> 
    <label for="chat-username">User: </label> 
    <input type="text" id="chat-username" class="chat__username" ng-model="chat.username" required> 
    <label for="chat-input">Chat: </label> 
    <input type="text" id="chat-input" class="chat__input" on-enter="sendChat()" ng-model="chat.message" required> 
    <a href="#" class="chat__submit icon-comments" id="chat-submit" ng-click="sendChat()" ng-disabled="isChatValid()">Chatme</a> 
</form> 


//**Javascript** 
app.controller('formCtrl',function($scope,Chats){ 
    $scope.sendChat = function() { 
    if($scope.isChatValid()) { 
     return; 
    } 
    console.log(JSON.stringify($scope.chat)); 
    var msg = {}; 
    angular.copy($scope.chat,msg); 
    Chats.data.push(msg);  
    }; 

    $scope.isChatValid = function() { 
    return $scope.chatForm.$invalid; 
    }; 
}); 

Problem jest wartość wejścia (message) nie jest zapisany w modelu Zakres (chat). Jeśli usuniemy dyrektywę onenter, to działa. Czego tu mi brakuje? Każda pomoc będzie wspaniała.

Odpowiedz

12

Ok to wymyśliłem. Okazuje się, że definiując obiekt zakresu w dyrektywie, tworzysz nowy zakres podrzędny. Szczegóły znaleźć tutaj:

Directive with scope breaking ngmodel of an input

Aby rozwiązać ten problem usunąłem deklarację scope i używane wartości funkcji z attrs obiektu.

dyrektywa wygląda to teraz:

app.directive('onEnter',function() { 

    var linkFn = function(scope,element,attrs) { 
    element.bind("keypress", function(event) { 
     if(event.which === 13) { 
     scope.$apply(function() { 
     scope.$eval(attrs.onEnter); 
     }); 
     event.preventDefault(); 
     } 
    }); 
    }; 

    return { 
    link:linkFn 
    }; 
}); 

Pełny kod w plunker

+0

ah nie widziałem, że masz go również – shaunhusain

+1

osobiście nie podoba mi się to rozwiązanie, ponieważ używa $ eval – Iamisti

+1

Na początku miałem tę samą opinię co @lamisti. Jednak zdałem sobie sprawę, że to rozwiązanie ma dużą zaletę - nie tworzy zakresu izolowania, więc nie będzie konfliktów z innymi potencjalnymi dyrektywami z zakresem izolatu, które mogą być zastosowane do tego samego elementu DOM. – Klon

1

Należy użyć $parent odnieść się do obiektu chat jak ten

$parent.chat.message 

Ponieważ używasz dyrektywy, które deklaruje zakres podrzędny. Oto pełna html:

<input type="text" id="chat-input" class="chat__input" on-enter="sendChat()" ng-model="$parent.chat.message" required> 
+0

dziękuję za odpowiedź @ sza, zorientowałem się, że to było coś w rodzaju i rozwiązałem to: –

3

Dla kątowym 1,2 napisałem tak:

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

app.directive('onEnter', function() { 
    return { 
     scope: {onEnter: '&'}, 
     link: function(scope, element) { 
      console.log(scope); 
      element.bind("keydown keypress", function(event) { 
       if(event.which === 13) { 
        scope.onEnter(); 
        scope.$apply(); 
       } 
      }); 
     } 
    } 
}); 
+0

ulepszone rozwiązanie byłoby: zasięg. $ Apply (function() { scope.onEnter(); }); – Iamisti

0

w odpowiedzi na @zool:

musiałem zmodyfikować swoją odpowiedź w następujący sposób, aby uniknąć mojej funkcji onEnter nazywany jest dwukrotnie:

[...] 
if(event.which === 13) { 
    event.preventDefault(); 
    scope.onEnter(); 
    scope.$apply(); 
} 
[...] 

zobaczyć również AngularJS form not submitting when pressing enter

Powiązane problemy