angularjs-pdf icon indicating copy to clipboard operation
angularjs-pdf copied to clipboard

Isolate scope

Open NicoBurno opened this issue 7 years ago • 12 comments

Why this directive do not use isolate scope instead of ng-controller? If you need help with this - then I can help.

There is also a non-critical flaw: there are best practice - to return module.name to export default

NicoBurno avatar Jun 05 '17 11:06 NicoBurno

Hi @NicoBurno, thanks for opening this issue. I know @endorama is working on isolating directive's scope, but any help will be appreciated.

@endorama can you please push your WIP as a PR?

dennybiasiolli avatar Jun 05 '17 12:06 dennybiasiolli

@dennybiasiolli thank you for your prompt response!

We forked the project and today we will make appropriate changes. I will share code in this Issue

NicoBurno avatar Jun 05 '17 12:06 NicoBurno

@dennybiasiolli In our code, many improvements have been made, mainly relating to the optimization... Backward compatibility and code-style are preserved.

Is it more convenient for you to get several ordered PRs or one big PR in several commits?

NicoBurno avatar Jun 05 '17 14:06 NicoBurno

@NicoBurno thanks again, one PR-per-improvement would be great, so we can review faster 😉

dennybiasiolli avatar Jun 05 '17 14:06 dennybiasiolli

@dennybiasiolli OK. Until tomorrow we will put everything in order :thumbsup:

NicoBurno avatar Jun 05 '17 15:06 NicoBurno

Sorry, I hurried to conclusions about backwards compatibility.

There were several ways to ensure backward compatibility with ngController, but they all have significant drawbacks:

We can use a variable for scope in the link-function.

Example:

{
  scope: {
    pdfUrl: '<'
  },
  require: '?^ngController',
  link(iScope, element, attrs, ngCtrl) {
    let scope = iScope;

    if (ngCtrl && !attrs.pdfUrl) {
      // ngController annotate detected
      scope = scope.$parent;
    }
  }
}

But this does not solve the problem of bindings in a template (they break when you switch to the isolated scope)

We can use the getter to get variables from scope

Example:

const getScopeField = (scope, field) => {
  return scope[field] || scope.$parent[field];
}

{
  scope: {
    pdfUrl: '<'
  },
  require: '?^ngController',
  link(scope, element, attrs, ngCtrl) {
    if (ngCtrl && !attrs.pdfUrl) {
      // ngController annotate detected
      scope.pdfUrl = getScopeField(scope, 'pdfUrl');
    }
  }
}

But that's just in case we do not need an update

Also there is a variant with scope.$parent.$watch ...

... But this is already dark magic

NicoBurno avatar Jun 05 '17 21:06 NicoBurno

There is also the idea of converting the directive to an angular Component, isolating the scope and moving the template part outside the component. With this, we can interact with the component with events allowing users to customize their templates outside the component. We will lost backward compatibility, but we can release a major version of ngPdf with breaking changes. What do you think about this?

dennybiasiolli avatar Jun 06 '17 06:06 dennybiasiolli

@dennybiasiolli angular-component is just a angular-directive with a limited API. In the case of our library, it makes no sense to make the component. All that the component can do - you can make a directive.

If you refuse backward compatibility when going to an isolated area, then there will be no problems with the directive.

Should I do the PR without backward compatibility? If so, which branch?

NicoBurno avatar Jun 06 '17 07:06 NicoBurno

Ok @NicoBurno, you can make the PR starting from branch master, thanks!

dennybiasiolli avatar Jun 06 '17 07:06 dennybiasiolli

Hello @dennybiasiolli @NicoBurno, sorry for the late replay! Do you still need my WIP or @NicoBurno implementation is already better than mine? :) You can check out mine here.

Granted, my work was just a quick WIP from a couple hours of hacking around the refactor!

Let me know!

endorama avatar Jun 06 '17 21:06 endorama

Thanks @endorama, please submit your WIP so we can take a look, thanks! 😄

dennybiasiolli avatar Jun 07 '17 07:06 dennybiasiolli

@endorama thanks for the answer!

I reviewed your implementation. This implementation is much better than the previous one =) Perhaps we could use this implementation in our product...

But, if we want to adhere to the best practices of angular-development, then we should abandon ngPdfFactory - it unnecessarily complicates the API. The best solution would be to bind configuration to directive's props.

@dennybiasiolli, @endorama I would suggest waiting until the end of the week, when I can return to work with ngPdf. And after that, you decide which implementation to take as the basis for the future major-version.

NicoBurno avatar Jun 07 '17 07:06 NicoBurno