0

I started to learn Angular not so long time ago and I'm trying to understand scope, binding and etc.

I have an order details controller:

orderApp.controller('OrderDetailsController', ['$http','$routeParams','$scope','config', function($http, $routeParams, $scope, config){

    var orderCtrl = this;
    orderCtrl.orderId = $routeParams.orderId;
    orderCtrl.order = {};
    orderCtrl.editingView = false;

   ...

}]);

On order details page I want to output all information about selected order. Also we need to give user ability to edit order. Information about editing mode is stored in orderCtrl.editingView.

I decided to create custom directive. If edit mode is off - display text, otherwise display input.

    orderApp.directive('editableText', function(){
    return {
        restrict: 'E',
        scope: {
            property: '=property',
            editMode: '=editMode'
        },
        controller: 'OrderDetailsController',
        controllerAs: 'orderCtrl',
        templateUrl: '/pages/editable-text.html'
    }
});

This is template:

<div class="col-xs-8" ng-if="!editMode">{{property}}</div>
<div class="col-xs-8" ng-if="editMode"><input type="text" class="form-control" ng-model="property"></div>

And this is how I use directive in html files:

 <editable-text property="orderCtrl.order.coid" edit-mode="orderCtrl.editingView"></editable-text>

Text and input are switching when edit mode is on/off. Problem is that orderCtrl.order.coid property is not updated when I change it in input.

Before edit property looks like: enter image description here

Turn on edit mode and change value: enter image description here

Turn off edit mode and we see old value: enter image description here

Do I need to synchronise controller values and directive scope? I thought that with 2-ways binding it should happen automatically. Probably there is any other way to write this functionality? Will appreciate any help.


UPD

Directive code:

    orderApp.directive('editableText', function(){
    return {
        restrict: 'E',
        bindToController: {
            property: '=property',
            editMode: '=editMode'
        },
        controller: 'OrderDetailsController',
        controllerAs: 'orderCtrl',
        templateUrl: '/pages/editable-text.html'
    }
});

Directive template:

<div class="col-xs-8" ng-if="!orderCtrl.editMode">{{orderCtrl.property}}</div>
<div class="col-xs-8" ng-if="orderCtrl.editMode"><input type="text" class="form-control" ng-model="orderCtrl.property"/></div>

Directive usage:

 <editable-text property="orderCtrl.order.coid" edit-mode="orderCtrl.editingView"></editable-text>

I'm not sure that we really need to pass edit-mode attribute.

1 Answer 1

1

You should use bindToController: { ..scope properties.. } option here inside your directive to make sure that isolated scope properties should get bounded to controller this context.

Directive

orderApp.directive('editableText', function(){
    return {
        restrict: 'E',
        bindToController: {
            property: '=property',
            editMode: '=editMode'
        },
        controller: 'OrderDetailsController',
        controllerAs: 'orderCtrl',
        templateUrl: '/pages/editable-text.html'
    }
});

Template

<div class="col-xs-8" ng-if="!orderCtrl.editMode">
     {{orderCtrl.property}}
</div>
<div class="col-xs-8" ng-if="orderCtrl.editMode">
   <input type="text" class="form-control" ng-model="orderCtrl.property"/>
</div>

Note:- this above bindToController: { ..scope properties.. } option available for angular 1.4+ versions.

For Angular 1.3 > version & 1.4 > version you should use former way of doing it by having bindingToController: true to bind scope variable to controller context & do keep the varaibles inside scope: { ...props... }

scope: {
    property: '=property',
    editMode: '=editMode'
},
bindToController: true
Sign up to request clarification or add additional context in comments.

7 Comments

Thanks for reply. I tried code and value is not displayed at all. Should I change the way of passing attributes to directive?
could you please try udpated? & i don't understand one thing, how orderCtrl directive controller instance available for directive controller instantiate.. as I can see you have used it over here <editable-text property="orderCtrl.order.coid" edit-mode="orderCtrl.editingView"></editable-text>
Yes, it works. Do I understand right that there is no need to pass editMode parameter to directive? I can just directly use "orderCtrl.editingView" in directive template. What do you think?
@Tamara I think you misunderstood my answer..there is need to pass editMode parameter to directive so that directive scope will become isolated scope.. could you create plunkr of your problem..so that I can make help on it..
Ok, I have updated my post. I'm not sure that I call directive in a right way. But we need to pass at least 1 parameter/attribute to the directive - name of the property we want to display.
|

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.