0

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.

1 Answer 1

1

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>
Sign up to request clarification or add additional context in comments.

2 Comments

Thank you for the detailed explanation and the code. That worked! I'm new to Angular so still learning but appreciate your help. Any reason why my post was voted down?
A more experienced user may be able to better clarify, but my best guess is that the question was down voted because your plunk did not initially run the way you explained it. I had to make a number of unrelated changes to get it to a running state. Make sure your example code behaves exactly how you have explained in your questions.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.