pBlackmouth
pBlackmouth

Reputation: 60

angularjs directive link function not binding data from Controller

I have a directive that makes use of jquery events on the element parameter of the link function, this directive has an input that is binding to a value that is obtained from the main controller of the page, passed through nested directives in a isolated scope , but when changing the value in the input is not reflected in the original object from controller.

The object has the following structure: Invoice 1: - Product 1 - Product 2 Invoice 2: - Product 3 - Product 4

When I change the amount of the invoice, the value is updated in the main controller, but when I change the amount of the product the change is not reflected.

This is my directive, what you should do is that when the user clicks on the value an input appears to be able to edit the value of the model:

eFieldTemplate.html

<div>
<div ng-if="IsMouseIn">
    <input type="text" ng-model="value" class="form-control input-sm" />
</div>
<div ng-if="IsMouseOut"  ng-click="OnMouseClick()">
    {{value}}
</div>
<div ng-if="MouseClick">
    <input  type="text" ng-model="value" class="form-control input-sm" />
</div>

eFieldDirective.js

 angular.module("appDirectives").directive("eField", function () {
    return {
        restrict: "E",
        templateUrl: "eFieldTemplate.html",
        scope: {
            value: "="
        },
        controller: function ($scope) {
            $scope.IsMouseOut = true;
            $scope.IsMouseIn = false;
            $scope.MouseClick = false;
            $scope.OnMouseEnter = function () {
                if (!$scope.MouseClick) {
                    $scope.IsMouseOut = false;
                    $scope.IsMouseIn = true;
                    $scope.MouseClick = false;
                }
            }

            $scope.OnMouseLeave = function () {
                if (!$scope.MouseClick) {
                    $scope.IsMouseOut = true;
                    $scope.IsMouseIn = false;
                    $scope.MouseClick = false;
                }
            }

            $scope.OnMouseClick = function () {
                    $scope.IsMouseOut = false;
                    $scope.IsMouseIn = false;
                    $scope.MouseClick = true;
            }

            $scope.EndEdit = function () {
                $scope.IsMouseOut = true;
                $scope.IsMouseIn = false;
                $scope.MouseClick = false;
            }
        },
        link: function (scope, el, attrs) {
            el.on("mouseenter", function () {
                scope.OnMouseEnter();
                scope.$apply();
            });

            el.on("mousemove", function () {
                scope.OnMouseEnter();
                scope.$apply();
            });

            el.on("mouseleave", function () {
                scope.OnMouseLeave();
                scope.$apply();
            });

            el.on("click", function () {
                scope.OnMouseClick();
                if (el[0].querySelector('input'))
                    el[0].querySelector('input').select();
                scope.$apply();
            });
        }
    };
});

Any Suggestions?

I give the example here: Plunker

UPDATED

I found a solution using ngIf, and is to reference a variable from the parent scope using $ parent.value. Eg.

<Input type="text" ng-model="$parent.value" class="form-control input-sm" />

Or also referring to another object eg.

<input type="text" ng-model="value">
<div ng-if="IsMouseIn">
    <input type="text" ng-model="value">
</div>

Here is the reference link: what is the difference between ng-if and ng-show/ng-hide

Upvotes: 1

Views: 827

Answers (2)

Farzad Salimi Jazi
Farzad Salimi Jazi

Reputation: 760

If you want to use ng-if not ng-show still, define $scope.values and $scope.config and use like this. To avoid the ng-if problem you should define an object.

    <div>
<div ng-if="config.IsMouseIn">
    <input type="text" ng-model="values.value" class="form-control input-sm" />
</div>
<div ng-if="config.IsMouseOut"  ng-click="OnMouseClick()">
    {{values.value}}
</div>
<div ng-if="config.MouseClick">
    <input  type="text" ng-model="values.value" class="form-control input-sm" />
</div>

Upvotes: 1

joe
joe

Reputation: 1489

using ng-if makes it create/destroy new html nodes and it seems to be unable to cope with that. change to ng-show and it will work. i also added a body mouse capture so it ends the edit.

<div>
<div ng-show="IsMouseIn">
    <input type="text" ng-model="value" class="form-control input-sm" />
</div>
<div ng-show="IsMouseOut"  ng-click="OnMouseClick()">
    {{value}}
</div>
<div ng-show="MouseClick">
    <input  type="text" ng-model="value" class="form-control input-sm" />
</div>

view plunker

Upvotes: 1

Related Questions