bindonce icon indicating copy to clipboard operation
bindonce copied to clipboard

rebind

Open romanesko opened this issue 11 years ago • 65 comments

Is it possible to force refresh of bindonce item?

romanesko avatar Dec 17 '13 08:12 romanesko

I had this usecase just today actually.

By removing the following line: https://github.com/Pasvaz/bindonce/blob/master/bindonce.js#L170

And adding scope.bindonceController = bindonceController; to the following line: https://github.com/Pasvaz/bindonce/blob/master/bindonce.js#L188

I can call $scope.bindonceController.runBinders(); whenever I want to manually update the DOM. It would be really helpful if the code could be changed to support this.

dominicglenn avatar Jan 16 '14 16:01 dominicglenn

I'm sorry to let you wait, I have to push some updates, one of them includes the possibility to refresh the binders by user request, I think that would close this issue. I just need a bit of time (very rare thing right now for me) to clean it and push it.

Pasvaz avatar Jan 16 '14 17:01 Pasvaz

As a follow up to this; I'm guessing you're redoing a lot of the binders themselves here as well?

This like the bo-class binding, or the bo-if need modifying to add or remove elements in either case, not just do the positive effect or nothing? (I'm modifying it myself at the moment for this purpose exactly).

dominicglenn avatar Jan 17 '14 17:01 dominicglenn

Probably should; I'm just doing it at work atm and not sure how they'd feel about me doing that. But I'll change it on my own and try submit a PR.

dominicglenn avatar Jan 17 '14 17:01 dominicglenn

I also have this use case and suggested #50 . The API could be bo-rebind="whateverEventName". bo-rebind would listen $on $rootScope for whateverEventName and call bindonceController.runBinders() from @dominicglenn 's suggestion.

What do you all think? I'm going to work on this for my own project this week - would others like this api?

cc @Pasvaz

rileylark avatar Jan 28 '14 14:01 rileylark

Soon (I think this weekend) I'll publish two new directives, one is onewatcher and the other is bo-refresh-on, bo-refresh-on works exactly as you thought, it uses $on to listen on the channel declared in the attribute boRefreshOn and it runs the binders again. There is another way to achieve this result, in my experimental version I use also a setter to attach a refresh function to the scope, something like bo-refresh-with="refreshMe" so when you call $scope.refreshMe() bindonce runs the binders. If I can test it enough I could publish also bo-refresh-with, let's see.

Pasvaz avatar Jan 28 '14 16:01 Pasvaz

Perfect, that's exactly what I had in mind. Thanks! Let me know if you can use help either implementing or testing.

rileylark avatar Jan 28 '14 20:01 rileylark

thank you @rileylark, I appreciate it.

Pasvaz avatar Jan 28 '14 22:01 Pasvaz

I've got some huge $watches dragging me down and will need to start work on this soon. I'll be happy to offer a PR but don't want to redo work you've already done. @Pasvaz, do you have a branch in progress I can extend?

rileylark avatar Feb 12 '14 16:02 rileylark

Hey,

I love the idea of using events, and the idea of one watcher will make a huge appeal to many people.

Is this planned for any time soon?

Thanks a lot.

Meligy avatar Feb 13 '14 05:02 Meligy

I'll try to push my branch today, I'm sorry I can't do it as soon as I thought but I'm facing some deadlines.

Pasvaz avatar Feb 13 '14 08:02 Pasvaz

Hey, no worries, bindonce will save me a ton of time even without this feature. I'd appreciate seeing your branch for this issue even incomplete - I'm sure I'll at least learn about your architecture by seeing where you've started, and maybe I can even help finish the implementation!

rileylark avatar Feb 13 '14 16:02 rileylark

I pushed the branch rebind-debug https://github.com/Pasvaz/bindonce/blob/rebind-debug/bindonce.js , it works but it's still embrional, I need to test it extensively and to rewrite/clean the code. It uses the directive refresh-on="message" and one-watcher to refresh the binders. Feel free to play with it but don't use it in production.

Pasvaz avatar Feb 14 '14 18:02 Pasvaz

@rileylark it would be nice if you and the others could be test the rebind-debug branch extensively in order to evidentiate the bugs or memory leaks so I can change or confirm the way it works.

Pasvaz avatar Feb 17 '14 11:02 Pasvaz

Thanks a bunch - I played with it some this weekend and will have some serious time this week.

rileylark avatar Feb 17 '14 15:02 rileylark

Hah, I hadn't seen your last comment when I posted. Yes, I'll be happy to send you some of my tests. Is the new demo folder a good place to put new uses?

I didn't have angular set up in the same build setup that you have, so in my initial test page I just included it from the CDN.

rileylark avatar Feb 17 '14 15:02 rileylark

feel free to modify the demo as you want or to create new ones, that branch is supposed to be a work in progress so it is quite wild. At the moment, the first approach was to emulate angular and so to destruct and rebuild each bo-directive, the next step will be to improve it and reuse elements instead of removing them in order to speed up the whole process.

Pasvaz avatar Feb 17 '14 17:02 Pasvaz

@Pasvaz I just sent you a PR with a simple demo for bo-src and bo-style.

I am not sure that $broadcast and $emit are going to be sufficient for my project. I am making a slide editor, with infrequently-changing slides. Each slide is represented twice: once in a long list of all of the previews, and again in the main editor area.

screen shot 2014-02-18 at 7 43 09 pm

These are sibling scopes, and each of my slides should have its own rebind-on event, so I think I would have to $emit the change up to $rootScope and then $broadcast them back down. Blegh!

I have an alternative idea to using the $scopes as event busses: a complementary bindonceNotify service that I can inject into any required code. My client code can call bindonceNotify('customUpdateEventName'), and your rebind-on api can register on a back end of the service. That way we can ignore the $scopes altogether, avoid muddying up the $on handlers, and have a kind of private channel for rebind notifications.

What do you think? I can submit another PR for this if you think it's a worthwhile direction to explore.

rileylark avatar Feb 19 '14 01:02 rileylark

I went ahead and sketched it out in #60

rileylark avatar Feb 19 '14 02:02 rileylark

Any further progress on rebind? :) I need this in an app I'm currently developing on :)

bugwelle avatar Feb 28 '14 14:02 bugwelle

@archer96 I've made an Angular fork that does this, it is at:

https://github.com/r3m0t/angular.js/tree/digest_limit

It is built at:

https://github.com/r3m0t/bower-angular tag: 1.2.14-build.local+sha.1289c58 or v1.2.15-build.local+sha.9660989

An example is at:

https://gist.github.com/r3m0t/9271790

Watch out, it works very differently from pasvaz.bindonce. You can use ng- for everything instead of bo-, but inside the new-once directive all the directives are affected.

r3m0t avatar Feb 28 '14 14:02 r3m0t

guys I'll complete it asap, right now I'm busy dealing with some deadlines. @archer96 could you test the rebind branch, it's not complete but some feedback could surely help.

Pasvaz avatar Feb 28 '14 20:02 Pasvaz

Hello,

I tried using that branch but there is one tiny "bug" that is annoying. Firstly my code:

<body ng-controller="MainCtrl">
<button ng-click="AddItem()">Add Item</button>
<button ng-click="RemoveFirstItem()">Remove First Item</button>
<ul>
    <li ng-show="!items">Items are not loaded, yet!</li>
    <li ng-show="items && !items.length">No items available!</li>
    <li bindonce="items" refresh-on="'rinfresca'" ng-repeat="item in items">
        <span bo-text="item.title"></span><br>
        <span bo-text="item.description"></span>
    </li>
</ul>
</body>

here my javsacript code:

var app = angular.module('bindoncedebug', ['pasvaz.bindonce']);

app.controller('MainCtrl', function ($scope, $q, $timeout) {

var count = 0;

$scope.AddItem = function () {
    $scope.items.push({
        title: 'Item ' + (++count),
        description: 'this is item number ' + count
    });
    $scope.$broadcast('rinfresca');
};

$scope.RemoveFirstItem = function () {
    $scope.items.shift();
    $scope.$broadcast('rinfresca');
};

$timeout(function () {
    $scope.items = [];
}, 1500)

$timeout(function () {
    $scope.items = [
        {
            title: 'Item 1',
            description: 'this is item number 1'
        },
        {
            title: 'Item 2',
            description: 'this is item number 2'
        },
        {
            title: 'Item 3',
            description: 'this is item number 3'
        }
    ];
    count = $scope.items.length;
}, 3000)

});

Rebind works well when putting refresh-onand bindonce on ul but when putting it on li it get following error when trying to remove an element:

TypeError: Object #<HTMLLIElement> has no method 'removeWatcher'
    at HTMLLIElement.ctrl.destroy (file:///Users/__myName__/github/local/bindonce/bindonce.js:176:12)
    at https://ajax.googleapis.com/ajax/libs/angularjs/1.2.13/angular.min.js:27:208
    at r (https://ajax.googleapis.com/ajax/libs/angularjs/1.2.13/angular.min.js:7:386)
    at Object.$c.c [as handle] (https://ajax.googleapis.com/ajax/libs/angularjs/1.2.13/angular.min.js:27:190)
    at cc (https://ajax.googleapis.com/ajax/libs/angularjs/1.2.13/angular.min.js:23:426)
    at Da (https://ajax.googleapis.com/ajax/libs/angularjs/1.2.13/angular.min.js:23:57)
    at r.remove (https://ajax.googleapis.com/ajax/libs/angularjs/1.2.13/angular.min.js:140:169)
    at Object.R.(anonymous function) [as remove] (https://ajax.googleapis.com/ajax/libs/angularjs/1.2.13/angular.min.js:141:414)
    at Object.leave (https://ajax.googleapis.com/ajax/libs/angularjs/1.2.13/angular.min.js:143:309)
    at https://ajax.googleapis.com/ajax/libs/angularjs/1.2.13/angular.min.js:187:25 

I'd like to use refresh-on on list elements as seen in this example.

Regards, Andre

bugwelle avatar Mar 01 '14 11:03 bugwelle

I am getting the same error as Andre when using https://github.com/Pasvaz/bindonce/blob/rebind-debug/bindonce.js

TypeError: Object #<HTMLSpanElement> has no method 'removeWatcher' at HTMLSpanElement.ctrl.destroy (https://mosaic-local.autodesk.com/lib/bower_components/angular-bindonce/bindonce.js:176:12) at HTMLSpanElement.bK.event.dispatch (https://staticfqa.staging.autodesk360beta.com/static/1.r343.2.r3/portal/script/core.js:26:43787) at HTMLSpanElement.ce.handle (https://staticfqa.staging.autodesk360beta.com/static/1.r343.2.r3/portal/script/core.js:26:39970) at Object.bK.event.trigger (https://staticfqa.staging.autodesk360beta.com/static/1.r343.2.r3/portal/script/core.js:26:42801) at bK.fn.extend.triggerHandler (https://staticfqa.staging.autodesk360beta.com/static/1.r343.2.r3/portal/script/core.js:26:51165) at removePatch as remove at https://mosaic-local.autodesk.com/lib/mosaic/angularjs/directives/infiniteScroll.dir.js:23:46 at wrappedCallback (https://mosaic-local.autodesk.com/lib/bower_components/angular/angular.js:11033:81) at https://mosaic-local.autodesk.com/lib/bower_components/angular/angular.js:11119:26 at Scope.$eval (https://mosaic-local.autodesk.com/lib/bower_components/angular/angular.js:12045:28)

Pasvaz, any idea on when you think you will have some time to look into this issue?

Thanks,

Raj

rajdeepg avatar Mar 03 '14 17:03 rajdeepg

@rajdeepg, please try it now

Pasvaz avatar Mar 03 '14 19:03 Pasvaz

Hi Pasvaz,

I just tried the latest and no longer getting the 'removeWatcher' error but also not seeing my ng-repeat update it self.

Here is the code I am using:

In My controller: var index = $scope.storageItems.indexOf(items[0]); $scope.storageItems[index].Name = items[0].Name; $scope.$broadcast('refreshStorageItemList'); $scope.$apply();

I am updating the Name field in the item and hoping that it refreshes in my grid but it is not refreshing? Is there something I am doing wrong?

If you can share some sample code on how this should work that will be great?

Thanks,

Raj

rajdeepg avatar Mar 03 '14 20:03 rajdeepg

+1 :) Following this interesting feature...

fidoboy avatar Mar 15 '14 16:03 fidoboy

I'm using bo-text and bo-class, and can confirm refresh-on is working with 31148e7. Thanks, Pasvaz!

dg192 avatar Mar 20 '14 17:03 dg192

I am trying to force refresh my table but its not refreshing. Can anyone please help me on how to do this?

HTML code:

<tbody bindonce="filteredItems" refresh-on="refreshTaskList" ng-repeat="task in filteredItems | orderBy:sortingOrder:reverse">
<tr>
 <td><span bo-bind="task.serviceTypeName | isEmpty : 'None'"></span></td>
  <td ><span bo-bind="task.percentageCompleted | isEmpty : 'Not Started'"></span></td>
</tr>
</tbody>

Controller code: $scope.$broadcast('refreshTaskList');

Please help me...

shansubra avatar Mar 29 '14 04:03 shansubra

Exciting feature! Any help needed besides testing?

trevordixon avatar Apr 23 '14 20:04 trevordixon