-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Implement multi-pagination in a single component #2665
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Thanks. Yes I've resorted to multiple child components and a custom pagination trait for now. I wish you didn't have to declare the variable and have it in an array too. It would be nice to just have the array. That's what I tried to achieve haphazardly in this PR #1997 |
Hi, yes I've done this way instead of storing the pagination into an associative array, like you've done in your PR because :
Now that the tests are passing, if Caleb feels good about this PR, we could talk about some syntax sugar to improve the DX. Using magic method we could even imagine, without an array to have this kind of syntax:
These methods would proxy the modification to the wanted properties, without the need to define them into an array: class ComponentWithMultiplePaginationStub extends Component
{
use WithPagination;
public $postsPage = 1;
public function render()
{
return view('show-name'[
'posts' => Post::paginate(3, ['*'], 'postsPage'),
'messages' => Message::paginate(3), // Will use the default $page attribute
]);
} The only down side to this it the fact that it creates a breaking change for those who've created custom pagination system or just Maybe this sugar syntax could be added into 3.0 |
Couldn't that be done with default values for the |
You mean default value to Yes it could be done that way but this would create a breaking change IMO for those who rely on the class ComponentWithPagination extends Component
{
use WithPagination;
// protected $paginatorNames = ['page' => 1]; // Default from WithPagination trait, just here for clarity
public function render()
{
return view('show-name', [ 'posts' => Post::paginate(3) ]);
}
} <span>
You are now on the page {{$page}}
</span> |
We could have the default parameter values, plus a default |
In such case, how to know which property should be changed? Another way to do would have to explicitly define the component to handle multiple pagination, or to not define the Doing so we could proxy the method to the Doing so, the developers explicitly know they can't use the |
I'm not sure if I understood the question, but how about we change whatever they specify, and change |
The question was about the previous comment:
How do we know which "page storage" to increment if the trait WithPagination {
public $page = 1;
public $pageNames = ['page' => 1];
}
I think this is what I just exposed before, we could have something like this: trait WithPagination {
public $page = 1;
public function setPage($page, $pageName = 'page') {
if ($pageName !== 'page' && property_exists($this, 'paginatorNames')) {
$this->paginatorNames[$pageName] = $page;
} else {
$this->page = $page;
}
}
} Doing so, the developer can still use the |
No you have this: trait WithPagination {
public $pageNames = ['page' => 1];
} and only change the array, and set public properties based on the array, and default to the name public function goToPage($page, $pageName = 'page') |
The problem here is the fact that it breaks the initial Laravel and livewire implementation and introduce a breaking change. I understood that you've built many components to workaround your previous PR, so you've created two components that rely on the native Imagine somewhere in your component view, you displayed the number of the page:
This code won't work anymore as this property won't exist anymore, the refactor code would be:
This is why we must keep the |
I haven't been able to communicate what i have in mind. It's not breaking at all. You can set public properties in php dynamically without declaring them in the class. We just need to find the right hook to initialize all the page number public properties based on the array before anyone tries to access them. The array is only the blueprint for dynamically setting the public properties. |
Ok, I think I got you. This should work but I dislike to work with dynamic properties (and so does my IDE 😄), but I'm totally open to the conversation: As you correctly said, we should search for the perfect hook to make sure the property is not accessed before its declaration, and actually we can't make sure of that: our best chance is probably the AFAIK, we cannot make sure someone didn't use the variable before any hook we could register from the trait. |
I understand this is a trade off. Elegance + accounting for 99% of the usage. Or ugly duplicate code + 100% of the theoretically possible cases. (excuse the emphatic language) |
No problem, we are here to debate and that's exactly why I pinged you :) For now I'm working on something else, so I can't dive into this for few days. But I'll modify the PR if needed. Maybe some feedback here @calebporzio to know what would be acceptable? |
Thanks for tackling this. Going to close this for now. More info here: #2727 |
1️⃣ Is this something that is wanted/needed? Did you create an issue / discussion about it first?
Yes, it's a wanted feature, multiple PR has previously opened and closed due to API breaking change.
2️⃣ Does it contain multiple, unrelated changes? Please separate the PRs out.
No, but it's an extension of a previous mandatory PR #2663 . I've spitted them as even if this one is not merged, the previous one is still a nice feature to have.
3️⃣ Does it include tests, if possible? (Not a deal-breaker, just a nice-to-have)
Yes, unit and browser
4️⃣ Please include a thorough description of the improvement and reasons why it's useful.
This PR gives us the ability to manage multiple pagination in a single component, using different properties to store the different page state and an array to store the name of each paginator:
The initial API is not broken, we now can just pass an additional parameter to select the paginator we want to increment/decrement or change:
Ping @mokhosh as I felt he was in demand of this feature.
5️⃣ Thanks for contributing! 🙌
Hopefully it will help some of us :)