Reputation: 693
I am playing around with Angular and came about an issue. The toggle I have set up on the Edit button works until I either click on the Save or Cancel button. Then it doesn't work anymore.
Here is my Plunker: http://plnkr.co/edit/Vy2WeUkk7jvIjp1z8Sfi
<section ng-controller="ContactController">
<ul class="list-group">
<li class="list-group-item" ng-repeat="contact in contacts">
<h3>
{{ contact.id }}
<em class="pull-right">{{contact.fname }} {{ contact.lname }} <button ng-click="editing = !editing">Edit</button></em>
<form ng-show="editing" ng-submit="editing = false" ng-controller="FormController">
<input type="hidden" ng-model="contact.id">
<label>First Name:</label>
<input type="text" ng-model="contact.fname" placeholder="first name" ng-required/>
<label>Last Name:</label>
<input type="text" ng-model="contact.lname" placeholder="last name" ng-required/>
<br/>
<button class="btn" ng-click="Save();" type="submit">Save</button>
<button class="btn" ng-click="editing = false">Cancel</button>
</form>
</h3>
</li>
</ul>
</section>
Any help would be appreciated.
Upvotes: 0
Views: 256
Reputation: 1207
The ng-repeat
directive creates a new scope for contact element it iterates. Let's call this the contact scope. Because the Edit button is within the contact scope, clicking it will create an editing
property on the contact scope.
When you use the ng-controller
directive to create a FormController
, you are creating a child scope, let's call it the form scope, whose prototype is the contact scope. This is why you can access properties from a parent scope directly from a child scope, and why the ng-show
directive initially works in your code.
However, when you click the Cancel button, you are setting the editing
property to false
directly on the form scope and this overrides the value of editing
on the contact scope. Since you are referencing editing
on the form scope in your ng-show
directive it is never going to show again since the Edit button modifies editing
on the contact scope.
The way to fix this is to use the scope's $parent
property whenever you are referencing editing in the form scope. This ensures you are watching and modifying editing
on the contact scope.
<section ng-controller="ContactController">
<ul class="list-group">
<li class="list-group-item" ng-repeat="contact in contacts">
<h3>
{{ contact.id }}
<em class="pull-right">{{contact.fname }} {{ contact.lname }} <button ng-click="editing = !editing">Edit</button></em>
<form ng-show="$parent.editing" ng-submit="$parent.editing = false" ng-controller="FormController">
<input type="hidden" ng-model="contact.id">
<label>First Name:</label>
<input type="text" ng-model="contact.fname" placeholder="first name" ng-required/>
<label>Last Name:</label>
<input type="text" ng-model="contact.lname" placeholder="last name" ng-required/>
<br/>
<button class="btn" ng-click="Save();" type="submit">Save</button>
<button class="btn" ng-click="$parent.editing = false">Cancel</button>
</form>
</h3>
</li>
</ul>
</section>
Upvotes: 1