Famous / famous-angular

Bring structure to your Famo.us apps with the power of AngularJS. Famo.us/Angular integrates seamlessly with existing Angular and Famo.us apps.
https://famo.us/angular
Mozilla Public License 2.0
1.92k stars 275 forks source link

Model binding doesn't work in fa-surface. #336

Open usagi-f opened 9 years ago

usagi-f commented 9 years ago

After I have changed a model from a view within 'fa-surface', if I rechanged the model by controller's function, it doesn't reflect to the view.


The version.


Example HTML

<body ng-controller="mainCtrl">

    <div class="block1">
        <textarea ng-model="one"></textarea>
        <button ng-click="clickone()">button 1</button>
    </div>

    <fa-app>
        <fa-surface>
            <div class="block2">
                <textarea ng-model="two"></textarea>
                <button ng-click="clicktwo()">button 2</button>
            </div>
        </fa-surface>
    </fa-app>

</body>

Example Javascript

.controller('mainCtrl', ['$scope', function($scope) {

    $scope.one = 'initial one';
    $scope.two = 'initial two';

    $scope.clickone = function() {
        $scope.one = 'clicked one';
    };

    $scope.clicktwo = function() {
        $scope.two = 'clicked two';
    };

}]);

Example steps

  1. initial view:
    • 'initial one'
    • 'initial two'
  2. click button 1:
    • 'clicked one' -- OK
    • 'initial two'
  3. edit first textarea:
    • 'editted one' -- OK
    • 'initial two'
  4. click button 1 again:
    • 'clicked one' -- OK
    • 'initial two'
  5. click button 2:
    • 'clicked one'
    • 'clicked two' -- OK
  6. edit second textarea:
    • 'clicked one'
    • 'editted two' -- OK
  7. click button 2 again:
    • 'clicked one'
    • 'editted two' -- Wrong!

Please confirm about the behavior above. Thanks.

SuPenguin commented 9 years ago

Hello,

You should use an object to store your ng-model value like this :

 $scope.input = {}
 $scope.input.one = 'initial one';
 $scope.input.two = 'initial two';

it avoids this kind of weird issue : http://codepen.io/Kelevra/pen/VYQaYa.

usagi-f commented 9 years ago

Thank you so much for your help. I appreciate it. That is so useful. I’ll try that way and check it if it works.

However I would like to know the fundamental solution about this issue.. If you know the solution, I would like you to teach me that.

Thank you.

jd-carroll commented 9 years ago

You are in two different scopes! When you declare fa-app you should list a controller, then your problem becomes a little more self evident.

When you click on the button, angular will start at the current scope and look for clicktwo(). If it doesn't find it, angular will traverse the tree of child-parent scope relationships looking for the first instance of clicktwo(). So when you click the button, the model is being updated correctly, but it's not being updated where you [should] think it is.

The use of ng-model binds the value to that scope. So the model is also being updated with the correct edited value (this time where you [should] expect it).

When you wrap your model in an input object, ng-model will search the current scope for that instance. When it doesn't find input in the current scope it will again traverse the child-parent scope tree until it finds and instance of input.

So the solution proposed by @SuPenguin is really pretty dangerous because it completely ignores the fact that you are on two different scopes.