2016-06-16 7 views
0

editable-table jQueryプラグインを使用してテーブルを編集可能にしています。使いやすく、軽く、効果的です。静的なhtml要素の変更時の角度データモデルの更新方法

マークアップはこれです:

<tr ng-repeat="o in orders"> 
    <td ng-bind="o.name"></td> 
    <td ng-bind="o.weight"></td> 
    <td ng-bind="o.dimensions"></td> 
</tr> 

テーブルを呼び出すことで編集可能に構成されます。表はきれいに表示され、それが編集可能である:

$('#ordertable').editableTableWidget(); 

をそれは非常によく動作します。データモデルが変更されると、テーブルも更新されます。

ただし、ng-bindを使用しているため、バインディングは一方向であり、テーブルの変更は自動的にデータモデルに伝播されません。入力フィールドではないため、ng-modelは機能しません。

私はAngularを初めて使うので、データモデルを更新する適切な方法がわかりません。私はプレーンなJSを使ってそれを行うことができましたが、私はそれをAngularの方法で行いたいと思います。

変更をモデルに反映させる正しい方法はどれですか?あなたは、角度は、あなたが行った変更を認識しないと、サイクルを消化するためにjqueryのモデルを使用してすべての変更が自動的に更新されることはありませんがトリガされていない、あなたが明示的にこの

$scope.$digest(); 
//but this will event not work 

のようなサイクルを消化トリガすることができます作るたび

答えて

0

値を更新する方法と編集可能なプラグインを混在させないでください。 Angularはプラグインのことを知らないので、そんなに協力することはできません。

ただ、プラグインなしでそれをやろう:

<tr ng-repeat="o in orders"> <td><input type="text" ng-model="o.name" /></td> <td><input type="text" ng-model="o.weight" /></td> <td><input type="text" ng-model="o.dimensions" /></td> </tr>

+0

は私の質問のために多くの偉大な答えがあります彼らのすべてがAngularについての私の理解を向上させたので、私はそれらすべてに感謝しています。しかし、私はそれが簡単であるためにこれを選択します。これは、少なくとも今のところ私が使用するソリューションです。 – marlar

0

モデルを更新してください。jqueryを使用している場合は、モデルに明示的に値を割り当てる必要があります

0

この問題を解決するための一つの他の方法があります。 jqueryのeditable-tableプラグインを使用する代わりに、表のセルで 'contenteditable'を使用し、ng-bindではなくng-modelを使用します。また、このコンテンツ編集可能な命令を記述してモデルを更新することもできます。このページの末尾にAngularJSサイト自体の例がありますhttps://docs.angularjs.org/api/ng/type/ngModel.NgModelController

私はそこから指示コードをコピーし、それに従ってあなたのhtmlを変更しました。

directive('contenteditable', ['$sce', function($sce) { 
 
    return { 
 
    restrict: 'A', // only activate on element attribute 
 
    require: '?ngModel', // get a hold of NgModelController 
 
    link: function(scope, element, attrs, ngModel) { 
 
     if (!ngModel) return; // do nothing if no ng-model 
 

 
     // Specify how UI should be updated 
 
     ngModel.$render = function() { 
 
     element.html($sce.getTrustedHtml(ngModel.$viewValue || '')); 
 
     }; 
 

 
     // Listen for change events to enable binding 
 
     element.on('blur keyup change', function() { 
 
     scope.$evalAsync(read); 
 
     }); 
 
     read(); // initialize 
 

 
     // Write data to the model 
 
     function read() { 
 
     var html = element.html(); 
 
     // When we clear the content editable the browser leaves a <br> behind 
 
     // If strip-br attribute is provided then we strip this out 
 
     if (attrs.stripBr && html == '<br>') { 
 
      html = ''; 
 
     } 
 
     ngModel.$setViewValue(html); 
 
     } 
 
    } 
 
    }; 
 
}]);

<tr ng-repeat="o in orders"> 
 
    <td contenteditable ng-model="o.name"></td> 
 
    <td contenteditable ng-model="o.weight"></td> 
 
    <td contenteditable ng-model="o.dimensions"></td> 
 
</tr>

+0

ng-bindの代わりにng-modelを使用すると、テーブルにデータはありません。ディレクティブ定義の$ sceは何を参照していますか? – marlar

+0

'ngSanitize'モジュールも追加します "angular.module( 'customControl'、['ngSanitize'])" – John

+0

このページの最後の例を参照してくださいhttps://docs.angularjs.org/api/ng /type/ngModel.NgModelController、その簡単な説明 – John

0

理想的には、角度のアプリでjQueryのベースのプラグインを使用しないでください。彼らはよく混じり合わない。同様の角度ベースのプラグインをよく探します。

私は何をしましたか? プラグインで使用されるinput要素を取得してユーザー入力(編集可能なセル)を取得し、angle $ compileサービスでコンパイルしました。

私はこれがうまくいくと思います。

HTML

<div ng-app='app' ng-controller='mainCtrl' my-input> 
    <table id="ir" > 
     <tr ng-repeat="o in orders"> 
     <td ng-repeat="(key, value) in o" ng-bind="value" ng-click="setCurrentCell($parent.$index, key)"></td> 
     </tr> 
    </table> 
</div> 

コントローラー

controller('mainCtrl', function($scope){ 
    setTimeout(function(){ 
     $('#ir').editableTableWidget(); 
    }); 

    $scope.orders = [{name:1, weight : 10}, {name:2, weight : 20}]; 
    var editableOrder = {}; 
    $scope.setCurrentCell = function(index, key){ 
     editableOrder.index = index; 
     editableOrder.key = key; 
    } 
    $scope.myEdit = function(newVal){ 
    $scope.orders[editableOrder.index][editableOrder.key] = newVal; 
    } 
}) 

指令

directive('myInput', ['$compile', function($compile){ 
    return { 
     restrict: 'A', 
     link: function(scope, element, attrs) { 
      setTimeout(function(){ 
       var input = element.find('input'); 
       input.attr('ng-model', 'val'); 
       input.attr('ng-change', 'myEdit(val)'); 
       $compile(input)(scope); 
      }) 
     } 
    } 
}]); 
関連する問題