[解決済み] AngularJS: モデル配列からモデル要素をスプライスすると、ng-repeatリストが更新されない
質問
2つのコントローラがあり、app.factory関数でデータを共有しています。
最初のコントローラは、リンクがクリックされたときに、モデルの配列(pluginsDisplayed)にウィジェットを追加します。ウィジェットは配列にプッシュされ、この変更はビューに反映されます (配列の内容を表示するために ng-repeat を使用します)。
<div ng-repeat="pluginD in pluginsDisplayed">
<div k2plugin pluginname="{{pluginD.name}}" pluginid="{{pluginD.id}}"></div>
</div>
このウィジェットは、k2plugin、remove、resizeの3つのディレクティブで構成されています。removeディレクティブは、k2pluginディレクティブのテンプレートにスパンを追加します。このスパンがクリックされると、共有配列の右側の要素が削除されます。
Array.splice()
. 共有配列は正しく更新されますが、その変更は
ではなく
でビューに反映されます。しかし、削除後に別の要素が追加されると、ビューは正しくリフレッシュされ、以前に削除された要素は表示されません。
私は何を間違えているのでしょうか?なぜこれが機能しないのか、説明していただけませんか。 私がAngularJSでやろうとしていることを行うためのより良い方法はありますか?
これは私のindex.htmlです。
<!doctype html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.5/angular.min.js">
</script>
<script src="main.js"></script>
</head>
<body>
<div ng-app="livePlugins">
<div ng-controller="pluginlistctrl">
<span>Add one of {{pluginList.length}} plugins</span>
<li ng-repeat="plugin in pluginList">
<span><a href="" ng-click="add()">{{plugin.name}}</a></span>
</li>
</div>
<div ng-controller="k2ctrl">
<div ng-repeat="pluginD in pluginsDisplayed">
<div k2plugin pluginname="{{pluginD.name}}" pluginid="{{pluginD.id}}"></div>
</div>
</div>
</div>
</body>
</html>
これは私のmain.jsです。
var app = angular.module ("livePlugins",[]);
app.factory('Data', function () {
return {pluginsDisplayed: []};
});
app.controller ("pluginlistctrl", function ($scope, Data) {
$scope.pluginList = [{name: "plugin1"}, {name:"plugin2"}, {name:"plugin3"}];
$scope.add = function () {
console.log ("Called add on", this.plugin.name, this.pluginList);
var newPlugin = {};
newPlugin.id = this.plugin.name + '_' + (new Date()).getTime();
newPlugin.name = this.plugin.name;
Data.pluginsDisplayed.push (newPlugin);
}
})
app.controller ("k2ctrl", function ($scope, Data) {
$scope.pluginsDisplayed = Data.pluginsDisplayed;
$scope.remove = function (element) {
console.log ("Called remove on ", this.pluginid, element);
var len = $scope.pluginsDisplayed.length;
var index = -1;
// Find the element in the array
for (var i = 0; i < len; i += 1) {
if ($scope.pluginsDisplayed[i].id === this.pluginid) {
index = i;
break;
}
}
// Remove the element
if (index !== -1) {
console.log ("removing the element from the array, index: ", index);
$scope.pluginsDisplayed.splice(index,1);
}
}
$scope.resize = function () {
console.log ("Called resize on ", this.pluginid);
}
})
app.directive("k2plugin", function () {
return {
restrict: "A",
scope: true,
link: function (scope, elements, attrs) {
console.log ("creating plugin");
// This won't work immediately. Attribute pluginname will be undefined
// as soon as this is called.
scope.pluginname = "Loading...";
scope.pluginid = attrs.pluginid;
// Observe changes to interpolated attribute
attrs.$observe('pluginname', function(value) {
console.log('pluginname has changed value to ' + value);
scope.pluginname = attrs.pluginname;
});
// Observe changes to interpolated attribute
attrs.$observe('pluginid', function(value) {
console.log('pluginid has changed value to ' + value);
scope.pluginid = attrs.pluginid;
});
},
template: "<div>{{pluginname}} <span resize>_</span> <span remove>X</span>" +
"<div>Plugin DIV</div>" +
"</div>",
replace: true
};
});
app.directive("remove", function () {
return function (scope, element, attrs) {
element.bind ("mousedown", function () {
scope.remove(element);
})
};
});
app.directive("resize", function () {
return function (scope, element, attrs) {
element.bind ("mousedown", function () {
scope.resize(element);
})
};
});
どのように解決するのですか?
jQueryでAjaxを呼び出したり、今回のように要素にイベントをバインドするなど、AngularJSの外で何らかの操作を行う場合は、AngularJSに自分自身を更新するように知らせる必要があります。以下は、そのためのコード変更です。
app.directive("remove", function () {
return function (scope, element, attrs) {
element.bind ("mousedown", function () {
scope.remove(element);
scope.$apply();
})
};
});
app.directive("resize", function () {
return function (scope, element, attrs) {
element.bind ("mousedown", function () {
scope.resize(element);
scope.$apply();
})
};
});
以下はそれに関するドキュメントです。 https://docs.angularjs.org/api/ng/type/$rootScope.Scope#$apply
関連
-
[解決済み] X-Frame-Options'を'SAMEORIGIN'に設定しているため、フレーム内での表示を拒否された。
-
[解決済み] 子 ng-repeat から親 ng-repeat のインデックスにアクセスする。
-
[解決済み] AngularJSのng-repeatは、空のリストのケースを処理します。
-
[解決済み] Jasmineの "callThrough "と "callFake() "の実用的な例が欲しい
-
[解決済み] AngularJSのng-repeatでキーと値を反復処理する方法は?
-
[解決済み] コントローラでフィルタを使用するには?
-
[解決済み] ServiceとFactoryで迷う
-
[解決済み] AngularJSでコントローラを2回実行する場合の対処法
-
[解決済み] AngularJSでEnterキーを押したときにフォームを送信する
-
[解決済み] AngularJSでモデルチェンジを見るとき、最初のロードを無視するにはどうすればいいですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] AngularJSのシンプルな "Hello, world "が動作しない。
-
[解決済み] シンプルなangularjsの日付入力
-
[解決済み] AngularJSの$parentは何を意味するのですか?
-
[解決済み] AngularJsでng-Cloakディレクティブを実際に使用する方法とは?
-
[解決済み] AngularJSの「href」と「ng-href」の違いについて
-
[解決済み] md-selectでデフォルト値を設定する方法
-
[解決済み] 新しい/分離されたスコープを求める複数のディレクティブ [ngController, ...] がある。
-
[解決済み] AngularJS 。scope.apply()呼び出し時の$digest already in progressエラーを防ぐ。
-
AngularJSのベストプラクティス。ng-repeatの$indexに注意する。
-
[解決済み] Angular.js: $evalの仕組みとバニラevalとの違いは何ですか?