質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

AngularJS

AngularJSはオープンソースのJavaScriptフレームワークです。ブラウザ上で動作するウェブアプリケーションの開発にMVCアーキテクチャを取り入れることを目的としています。

Q&A

解決済

2回答

3067閲覧

AngularJs 関数内のng-if

退会済みユーザー

退会済みユーザー

総合スコア0

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

AngularJS

AngularJSはオープンソースのJavaScriptフレームワークです。ブラウザ上で動作するウェブアプリケーションの開発にMVCアーキテクチャを取り入れることを目的としています。

0グッド

0クリップ

投稿2017/01/19 22:32

ng-ifを使って表示非表示切り替えをしたいのですが、
関数内では無効になってしまうのか、非表示にすることができません。

javascript

1 function showDays(days) { 2 for (var i = 1; i < days; i++) { 3 var uidi = i; 4 var uidm = month; 5 var uid = uidi.toString() + uidm.toString(); 6 $(".dates").append("<div class='date_item' data='" + uid + "'><span ng-if='display(foo)'>★</span>" + i + "</div>"); 7 } 8 }

最後の行の<span ng-if='display(foo)'></span>が無効になってしまい、常に表示されてしまいます。

ng-ifを有効にできる方法がありましたらご教授お願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

動的に追加された要素はangularに知らせてあげなければなりません。

また、AngularJSには元からjQuery liteが用意されているので、
jQueryを使わずにAngularに用意されているangular.element()を使いましょう。
また、全てのDOMからクラスを検索するのは負荷な上、想定されない動きをする可能性があるので、なるべく$elementを使いましょう。

$compileや$elementのロードをお忘れずに。

javascript

1var elem = angular.element("<div class='date_item' data='" + uid + "'><span ng-if='display(foo)'>★</span>" + i + "</div>"); 2 3angular.element(".dates").append($compile(elem)($scope)); //$elementを使わない場合 4 5$element.find(".dates").append($compile(elem)($scope)); //$elementを使う場合

投稿2017/01/20 01:04

編集2017/01/20 01:05
Everatch

総合スコア241

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2017/01/20 04:18

ご回答いただき誠にありがとうございます。 $compileや$elementのロードは以下の様な記述では間違えでしょうか? function showDays(days,$element,$compile) { for (var i = 1; i < days; i++) { var uidi = i; var uidm = month; var uid = uidi.toString() + uidm.toString(); var elem = angular.element("<div class='date_item' data='" + uid + "'><span ng-if='display(foo)'>★</span>" + i + "</div>"); $element.find(".dates").append($compile(elem)($scope)); //$elementを使う場合 } } リファレンスのほう確認いたしましたが、記述方法が分からず、大変無知で申し訳ありません… 宜しければご教授お願いいたします。
Everatch

2017/01/20 04:25 編集

コントローラの定義時に読み込みましょう、一例としてこういう風に記述できます。 myApp.controller('AppController', ['$scope', '$element', '$compile', function ($scope, $element, $compile) { //hogehoge }]);
退会済みユーザー

退会済みユーザー

2017/01/20 08:54

大変ご丁寧にありがとうございます。 教えて頂きました通りに記述し、コントローラでの$compile、$elementのロードができました。 しかし、.dates に<div class='date_item' data='" + uid + "'><span ng-if='display(foo)'>★</span>" + i + "</div>が付与されません。 可能性としてどのようなことが考えられますでしょうか? 何度も質問を重ねてしまい申し訳ありません。 コードをこちらにアップしましたので、ご確認いただけますでしょうか。 よろしくお願い致します。
退会済みユーザー

退会済みユーザー

2017/01/21 11:15 編集

解決策を探しながら他の方法も探してみます。 この度はありがとうございました。
Everatch

2017/01/23 03:20

回答が遅くなって申し訳ございません、 質問者の状況がどのようになっているか把握できていないとなんとも言えませんので、 可能であればHTMLやコントローラ本体を追記していただけるとアドバイスしやすいです。
退会済みユーザー

退会済みユーザー

2017/01/23 23:37

ご回答ありがとうございます! http://codepen.io/bumsimdag/pen/gggJpa こちらにアップ致しましたので、js中間の★dayの部分を見て頂きたく思います。 よろしくお願い致します。
Everatch

2017/01/24 04:00 編集

わざわざありがとうございます! angular.elementの.find() は tagName限定みたいですね、失礼しました。 $element.find(".dates") を angular.element($element[0].getElementsByClassName("dates")) にしてみましょう! 参考:http://codepen.io/anon/pen/vgZRKO?editors=1010
退会済みユーザー

退会済みユーザー

2017/01/24 11:52

こちらの方こそ、わざわざお時間割いていただき誠にありがとうございます。 修正していただいたほうで無事ng-ifが使えることを確認いたしました! 必要最低限のDOM操作機能がもともとangularには組み込まれているのですね。 angularjsにおいてもjavascriptにおいてもまだまだ勉強不足で、すみません。 $elementというのから少しずつ勉強したいと思います。 そして本当に申し訳ありません、あと一つだけ質問させてください。 教えて頂いたコードをもとにng-ifでは、スケジュールが入った日付に★をつけるというものを 形にしたかったのですが、どのようにしてもうまくいきません。 eventsを登録することでevents.idが作られるので、event.idと日付が一致したときに ★を表示させる、という考え方では間違っておりますでしょうか? <span ng-if='events.id != null'>★</span>
Everatch

2017/01/24 12:12 編集

無理してやればできなくはありませんが、そもそもAngularの思想に従えば、JSに要素の生成を置くべきではないですね。Angularは双方向データバインドが強みの一つですので、templateを分けて、modelを駆使して実現した方が簡単にできます。感覚的に言えば、HTMLをjsで動的に追加するのではなく、HTMLをテンプレートに記述して、JS側のモデルを元に繰り返したり非表示にしたりするのがangularの正しい使い方かと思います。 ちなみに無理すれば、controllerで $scope.hasEvent() を作って、html側で ng-if="hasEvent(uid)" を書くことで実現できます。 ($compileでコンパイルできるものはあくまでも$scopeを継承しているので、this (controllerAs)は使えません。)
Everatch

2017/01/24 12:22

説明が煩雑だったので、良い例と悪い例を下に書きました、参考になれればよいかと。
退会済みユーザー

退会済みユーザー

2017/01/24 15:26

最後までご丁寧に教えて頂きありがとうございます。 いただいた例をもとに作ってみます! この度は本当にありがとうございました!
guest

0

#悪い例

html

1<div id="test"></div>

javascript

1//コントローラなどの宣言は省きます 2for(let i=0; i<10; i++){ 3 let element = angular.element("<p>" + i + "</p>"); 4 angular.element(document.getElementById("test")).append($compile(element)($scope)); 5}

#良い例

html

1<div id="test"> 2 <p ng-repeat="n in ctrl.num">{{n}}</p> 3</div>

javascript

1//コントローラなどの宣言は省きます 2this.num = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];

投稿2017/01/24 12:21

Everatch

総合スコア241

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問